SQLite select order by alphabet first, then all other characters - sqlite

I have a SQLite db with a table, containing rows with different names. For example:
id
name
1
antony
2
%
3
10
4
stackoverflow
5
john
I get the data from this table with
SELECT * FROM table WHERE 1 ORDER BY name Asc LIMIT ?, ?
And it returns
id
name
2
%
3
10
1
antony
5
john
4
stackoverflow
But i want it to return names in alphabetical order first, then all other names which starts with non letters in the right order too. So i want to get:
id
name
1
antony
5
john
4
stackoverflow
2
%
3
10
How can i achieve that?

Use the operator GLOB to check if the name starts with a letter in the ORDER BY clause:
SELECT *
FROM tablename
ORDER BY name GLOB '[A-Za-z]*' DESC, name
See the demo.

Thanks to #forpas, just wish to add
If you wish to make Case insensitive sorting, you may try as below
SELECT *
FROM tablename
ORDER BY name GLOB '[A-Za-z]*' DESC, Upper(name)

Related

Parsing Database string in SQL Select command

So basically I have this column called Signature inserted in the database
Id = 1
Value = John, Micheal, Sara
Id = 2
Value = Mike, Steve, John
.
.
Now in asp.net I'm not sure how can I do select command and know if the value
John, Micheal, Sara
Has "Micheal" in it
To answer you question:
CHARINDEX() searches for a substring within a larger string, and returns the position of the match, or 0 if no match is found
SELECT * FROM [Table] WHERE CHARINDEX(Signature, 'Michael') > 0
Or
You can just use wildcards in the query (after IF, WHERE or ON):
SELECT * FROM [Table] WHERE Signature LIKE '%' + 'Michael' + '%'
But really you should be storing this data in a separate related table.
No. Don't.
Add a new table with rows for each signature name, and use a row for each signatory. That is the point of relational databases.
1 John
1 Michael
1 Sara
2 Mike
2 Steve
2 John
Or better still, add two new tables - one for the signatories, and one for the relation between that and your initial table
Signatories
1 John
2 Michael
ItemSignatures
ItemID SignatoryID
1 1
1 2
2 1
select *
from Signature
where value like '%Micheal%'

How to create a column for even and odd records dynamically?

I have a query in Teradata. I want to add an additional column that would be a VARCHAR.
It should say whether the selected record is even or odd
select id, name, CASE newColumn WHEN --- ???
from my table
Like this
id name newColumn
1 asdf odd
2 ts df even
32 htssdf odd
4 asdfsd even
23 gftht odd
How can I do this
Based on your example, I can't tell how you are sorting the results. You would need to define a sort order. Let's assume you would do it based on the id number.
SELECT id, name,
ROW_NUMBER() OVER(ORDER BY id) row_id,
CASE WHEN ROW_NUMBER() OVER(ORDER BY id) MOD 2 = 0 THEN 'Even' ELSE 'Odd' END newColumn
FROM my table
The row_id is incrementally assigned based on the id field being sorted ascending. You then use the MOD function to determine if there's a remainder after dividing the number by a value (in this case 2). Result would look like the following:
id name row_id newColumn
1 asdf 1 Odd
2 ts df 2 Even
4 asdfsd 3 Odd
23 gftht 4 Even
32 htssdf 5 Odd

How can I concatenate(or merge) values from 2 result sets with the same PK?

I don't know if I'm being dumb here but I can't seem to find an efficient way to do this. I wrote a very long and inefficient query that does what I need, but what I WANT is a more efficient way.
I have 2 result sets that displays an ID (a PK which is generic/from the same source in both sets) and a FLAG (A - approve and V - Validate).
Result Set 1
ID FLAG
1 V
2 V
3 V
4 V
5 V
6 V
Result Set 2
ID FLAG
2 A
5 A
7 A
8 A
I want to "merge" these two sets to give me this output:
ID FLAG
1 V
2 (V/A)
3 V
4 V
5 (V/A)
6 V
7 A
8 A
Neither of the 2 result sets will at any time have all the ID's to make a simple left join with a case statement on the other result set an easy solution.
I'm currently doing a union between the two sets to get ALL the ID's. Thereafter I left join the 2 result sets to get the required '(V/A)' by use of a case statement.
There must be a more efficient way but I just can't seem to figure it out now as I'm running low on amps... I need a holiday... :-/
Thanks in advance!
Use a FULL OUTER JOIN:
SELECT ID,
CASE
WHEN t1.FLAG IS NULL THEN t2.FLAG
WHEN t2.FLAG IS NULL THEN t1.FLAG
ELSE '(' || t1.FLAG || '/' || t2.FLAG || ')'
END AS MERGED_FLAG
FROM TABLE1 t1
FULL OUTER JOIN TABLE2 t2
USING (ID)
ORDER BY ID
See this SQLFiddle.
Share and enjoy.
I think that you can use xmlagg. Here an exemple :
SELECT deptno,
SUBSTR (REPLACE (REPLACE (XMLAGG (XMLELEMENT ("x", ename)
ORDER BY ename),'</x>'),'<x>','|'),2) as concated_list
FROM emp
GROUP BY deptno
ORDER BY deptno;
Bye

Counting Duplicates from table

I have got a table which i have mentioned below, i need to get a total results avoiding duplicates , can any one provide any assistance or suggestions on how to get the results mentioned below, thankyu
ID name Total Used
24 John 5 2
24 John 10 6
27 Peter 20 0
27 Peter 20 5
Result should be something like this
ID name Total Used
24 John 15 8
27 Peter 40 5
Looks like you just need to use SUM() on the two columns. Also use a GROUP BY on the id and name
SELECT id, name, sum(total) All_total, sum(used) All_used
FROM yourtable
GROUP BY id, name
see SQL Fiddle with Demo
The GROUP BY field must include any other columns you are selecting which are not in an aggregate function, so for the example you would include both id and name in the GROUP BY.
Edit #1 your query would be:
SELECT [ID] , name, sum([Total]), sum([Used]), [GUID]
FROM [table].[dbo].[vw_data]
GROUP BY [ID], [name], [GUID]
select sum(Total), sum(Used), ID, name
from table
group by ID, name;
select ID, name, sum( Total,), sum( Used)
from table
group by Id,name;
Try this:
select id,name, sum(Total),sum(used)
from tab
group by id,name
SELECT id, name, sum(total) total, sum(used) used from table GROUP BY id, name
MySql syntax for this problem:
CREATE TABLE DUPLICATE (ID,NAME, TOTAL, USED);
INSERT INTO DUPLICATE VALUES(24,'John',5,2);
INSERT INTO DUPLICATE VALUES(24,'John',10,6);
INSERT INTO DUPLICATE VALUES(27,'Peter',20,0);
INSERT INTO DUPLICATE VALUES(27,'Peter',20,5);
SELECT ID, NAME, SUM(TOTAL), SUM(USED) FROM DUPLICATE GROUP BY ID, NAME;

Filtering in Oracle based on a group of values contained in a list of values

I have following two tables:
ID_PERSON NAME
-----------------
1 John
2 Joe
3 Peter
ID_PERSON ID_SPECIALIZATION
------------------------------
1 5
1 6
1 7
2 5
2 1
3 6
3 10
I need to filter data based on group of ids ID_SPECIALIZATION that will be provided. For example
I want to display only those persons who has specialization in 5 and 6 so it will return only first person. In ASP.NET Web form there will be two listboxes, left and right button, in first LB there will be all possible specializations and user will choose some of them to second LB as filtering options. I have no idea how to put this filtering condition in sql query. Thanks for help.
You could use the following:
SQL> SELECT p.id_person, p.NAME
2 FROM person p
3 JOIN person_spe s ON p.id_person = s.id_person
4 WHERE id_specialization IN (5, 6)
5 GROUP BY p.id_person, p.NAME
6 HAVING COUNT(*) = 2;
ID_PERSON NAME
---------- -----
1 John
One way to do it:
SELECT
ID_PERSON
, NAME
FROM
Person AS p
WHERE EXISTS
( SELECT *
FROM
PersonSpecialization AS ps
WHERE ps.ID_PERSON = p.ID_PERSON
AND ps.ID_SPECIALIZATION = 5
)
AND EXISTS
( SELECT *
FROM
PersonSpecialization AS ps
WHERE ps.ID_PERSON = p.ID_PERSON
AND ps.ID_SPECIALIZATION = 6
)
SELECT d1.id_person, d1.name FROM tbl_table1 d1
INNER JOIN tbl_table2 d1
ON d1.ID_PERSON=d2.ID_PERSON
WHERE ID_SPECILIZATION = ?
Theres the query but I'm not sure how asp.net works and passing in the value. It might be work looking up bind variables which allows you to use place holders in the sql which oracle then caches the query and just uses the values that you pass in at run tuime using EXECUTE IMMEDIATE.

Resources