How can I get sets of 2 entries where each set starts with a different letter and no letter is repeated from a sqlite database? - sql

Like this:
apple
aardvark
banana
bet
cow
car
...
zipper
zoo
Assuming the database has more than just two different entries that start with any of the letters. I was thinking of doing something with TOP and wildcards, but I don't really know enough about SQL to pull this off. What can I do?

You can do this with the substr function and a correlated subquery:
SELECT *
FROM YourTable a
WHERE wordField IN (SELECT wordField
FROM YourTable AS b
WHERE substr(a.wordField ,1,1) = substr(b.wordField ,1,1)
ORDER BY wordField
LIMIT 2)
Demo: SQL Fiddle
You can use the ORDER BY to adjust which 2 records are returned. Like ORDER BY RANDOM() if that's supported.

Related

Alternative for GROUP BY and STUFF in SQL

I am writing some SQL queries in AWS Athena. I have 3 tables search, retrieval and intent. In search table I have 2 columns id and term i.e.
id term
1 abc
1 bcd
2 def
1 ghd
What I want is to write a query to get:
id term
1 abc, bcd, ghd
2 def
I know this can be done using STUFF and FOR XML PATH but, in Athena all the features of SQL are yet not supported. Is there any other way to achieve this. My current query is:
select search.id , STUFF(
(select ',' + search.term
from search
FOR XML PATH('')),1,1,'')
FROM search
group by search.id
Also, I have one more question. I have retrieval table that consist of 3 columns i.e.:
id time term
1 0 abc
1 20 bcd
1 100 gfh
2 40 hfg
2 60 lkf
What I want is:
id time term
1 100 gfh
2 60 lkf
I want to write a query to get the id and term on the basis of max value of time. Here is my current query:
select retrieval.id, max(retrieval.time), retrieval.term
from search
group by retrieval.id, retrieval.term
order by max(retrieval.time)
I am getting duplicate id's along with the term. I think it is because, I am doing group by on id and term both. But, I am not sure how can I achieve it without using group by.
The XML method is brokenness in SQL Server. No reason to attempt it in any other database.
One method uses arrays:
select s.id, array_agg(s.term)
from search s
group by s.id;
Because the database supports arrays, you should learn to use them. You can convert the array to a string:
select s.id, array_join(array_agg(s.term), ',') as terms
from search s
group by s.id;
Group by is a group operation: think that you are clubbing the results and have to find min, max, count etc.
I am answering only one question. Use it to find the answer to question 1
For question 2:
select
from (select id, max(time) as time
from search
group by id, term
order by max(time)
) search_1, search as search_2
where search_1.id = search_2.id
and search_1.time = search_2.time

How to show blank instead of column value for all duplicated columns of a SQL query?

There is a similar question which answer this for a known number of columns and only a single selection column. But the problem here is that
I have no knowledge of columns (count, type) of a specified SQL query and also I want to blank for all columns not a single column.
For example lets say I have following query.
Select * from View1
Result :
Column(1) Column(2) Column(..) Column(N)
1 A Sales 1500
2 C Sales 2500
3 C Sales 2500
4 A Development 2500
Expected result :
Column(1) Column(2) Column(..) Column(N)
1 A Sales 1500
2 C 2500
3
4 A Development
Pseudo SQL Query :
EXEC proc_blank_query_result 'Select * from View1'
If you're in SQL Server 2012 or newer, you can do this with lag, something like this:
select
nullif(column1, lag(column1) over (order by yourorderbyclause)) as column1,
nullif(column2, lag(column2) over (order by yourorderbyclause)) as column2,
...
from
View1
To make it dynamic, well then you have to parse a lot of metadata from the query. Using sp_describe_first_result_set might be a good idea, or use select into a temp. table and parse the columns of it.

sql query order by parts of

lets say you have a table with 10 000 records of different email adresses, but within this tables there are a few hundred (this can vary and should not matter) addresses that contains a specific domain name ie #horses.com.
I would like in one single query retrieve all 10 000 record, but the ones that contains #horses.com will always be on top of the list.
Something like this " SELECT TOP 10000 * FROM dbo.Emails ORDER BY -- the records that contains #horses.com comes first"
OR
Give me 10000 records from the table dbo.Emails but make shure everyone that contains "#horses.com" comes first, no matter how many there is.
BTW This is on an sql 2012 server.
Anyone??
Try this:
SELECT TOP 10000 *
FROM dbo.Emails
ORDER BY IIF(Email LIKE '%#horses.com', 0, 1)
This assumes the email ends in '#horses.com', which isn't unreasonable. If you really want a contains-like function, add another % after the .com.
Edit: The IIF function is only available in sql server 2012 and later, for a more portable solution use CASE WHEN Email LIKE '%#horses.com' THEN 0 ELSE 1 END.
SELECT TOP 10000 *
FROM dbo.Emails
ORDER BY case when charindex('#horses.com', email) > 0
then 1
else 2
end,
email
SELECT 1,* FROM dbo.Emails where namn like '%#horses.com%'
union
SELECT 2,* FROM dbo.Emails where namn not like '%#horses.com%'
order by 1

sqlite query unsorted result

I have list of Ids 31165,31160,31321,31322,31199,31136 which is dynamic.
When I run query
select id,name from master_movievod where id in(31165,31160,31321,31322,31199,31136);
I get following result
31136|Independence Day
31160|Planet of the Apes
31165|Mrs. Doubtfire
31199|Moulin Rouge
31321|Adult Movie 2
31322|Adult Movie 3
This is sorted list in ascending order.
I want the list in the same order which I give as input like
31165|Mrs. Doubtfire
31160|Planet of the Apes
31321|Adult Movie 2
31322|Adult Movie 3
31199|Moulin Rouge
31136|Independece Day
Without an order by clause, there's no guarantee on the order a database returns the results to you. SQLite, unfortunately, doesn't have something like MySQL's field for custom sorting, but you can jimmy-rig something with a case expression:
SELECT id, name
FROM master_movievod
WHERE id IN (31165, 31160, 31321, 31322, 31199, 31136)
ORDER BY CASE ID WHEN 31165 THEN 0
WHEN 31160 THEN 1
WHEN 31321 THEN 2
WHEN 31322 THEN 3
WHEN 31199 THEN 4
WHEN 31136 THEN 5
END ASC
Unfortunately, SQLite does not have an option like MySQL's FIELD for doing a custom ordering. You are left with two options. The first is that you could create a custom table containing the ordering you want and use that to sort. This option isn't very attractive. The second (and easier) option is to use ORDER BY CASE to achieve the order you want:
SELECT id, name FROM master_movievod
WHERE id IN (31165,31160,31321,31322,31199,31136)
ORDER BY
CASE id
WHEN 31165 THEN 0
WHEN 31160 THEN 1
WHEN 31321 THEN 2
WHEN 31322 THEN 3
WHEN 31199 THEN 4
WHEN 31136 THEN 5
END ASC

How do I preserve the order of a SQL query using the IN command

SELECT * FROM tblItems
WHERE itemId IN (9,1,4)
Returns in the order that SQL finds them in (which happens to be 1, 4, 9) however, I want them returned in the order that I specified in the array.
I know I could reorder them after in my native language (obj c), but is there a neat way to do this in SQL?
Somthing like this would be great:
ORDER BY itemId (9,1,4) -- <-- this dosn't work :)
Probably the best way to do this is create a table of item IDs, which also includes a rank order. Then you can join and sort by the rank order.
Create a table like this:
itemID rank
9 1
1 2
4 3
Then your query would look like this:
select tblItems.* from tblItems
inner join items_to_get on
items_to_get.itemID = tblItems.itemID
order by rank
Use a CASE expression to map the ID values to an increasing sequence:
... ORDER BY CASE itemId
WHEN 9 THEN 1
WHEN 1 THEN 2
ELSE 3
END
I had the same task once in a mysql environment.
I ended up using
ORDER BY FIND_IN_SET(itemID, '9,1,4')
this is working for me since then. I hope it also works for sqlite
You can add a case construct to your select clause.
select case when itemid = 9 then 1
when itemid = 1 then 2 else 3 end sortfield
etc
order by sortfield
You could create a procedure to order the data in SQL, but that would be much more complicated than its native language counterpart.
There's no "neat way" to resort the data like that in SQL -- the WHERE clause of a SELECT simply says "if these criteria are matched, include the row"; it's not (and it cannot be) an ordering criterion.