How do you keep the order using SELECT WHERE IN()? - sql

Is there a way to keep the order when using SELECT WHERE IN()? For example, using the following query:
SELECT id FROM data_table WHERE id IN(56,55,54,1,7);
The results will come back using the default order by id. 1,7,54,55,56
When I want to keep the order used in the IN: 56,55,54,1,7
Is there a quick way to do this in MySQL or will I be forced to order it after in code?

Use FIND_IN_SET:
ORDER BY FIND_IN_SET(id, '56,55,54,1,7')

You can also use FIELD:
ORDER BY FIELD(id, '56,55,54,1,7')
http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_field
http://ivanjovanovic.com/2008/04/01/preserving-ordering-with-where-in-clause-in-mysql/

You could do a UNION, that might return the order the same way.
BUT:
Why not just have your application reorder the results when it receives them, rather than forcing the DB to do it?

Related

SQL simple GROUP BY query

Is there a way to make a simple GROUP BY query with SQL and not use COUNT,AVG or SUM? I want to show all columns and group it with a single column.
SELECT * FROM [SPC].[dbo].[BoardSFC] GROUP BY boardsn
The query above is working on Mysql but not on SQL, is there a way to achieve this? any suggestion would be great
UPDATE: Here is my data I just need to group them by boardsn and get imulti equals to 1
I thing you just understand 'group data' in a different way than it is implemented in sql server. You simply want rows that have the same value together in the result and that would be ordering not grouping. So maybe what you need is:
SELECT *
FROM [SPC].[dbo].[BoardSFC]
WHERE imulti = 1
ORDER BY boardsn
The query above is working on Mysql but not on SQL, is there a way to achieve this? any suggestion would be great
No, there is not. MySQL only lets you do this because it violates the various SQL standards quite egregiously.
You need to name each column you want in the result-set whenever you use GROUP BY. The SELECT * feature is only provided as a convenience when working with data interactively - in production code you should never use SELECT *.
You could use a TOP 1 WITH TIES combined with a ORDER BY ROW_NUMBER.
SELECT TOP 1 WITH TIES *
FROM [SPC].[dbo].[BoardSFC]
ORDER BY ROW_NUMBER() OVER (PARTITION BY boardsn ORDER BY imulti)
Or more explicitly, use ROW_NUMBER in a sub-query
SELECT *
FROM
(
SELECT *, ROW_NUMBER() OVER (PARTITION BY boardsn ORDER BY imulti) as RN
FROM [SPC].[dbo].[BoardSFC]
) q
where RN = 1

How to get a distinct result ordered by a different column? SQL Postgresql

I'm trying to figure the best way to perform this query in postgresql. I have a messages table and I want to grab the last message a user received from each distinct user. I need to select everything from the row.
I would think this is where I want to group by the senders id "msgfromid", but when I do this it complains that I haven't included everything from my select statement in my group by statement, but I only want to group by the one column, not all of them. So if I try to use Distinct on the one column it forces me to order by the 'distinct on' column first ("msgfromid") which prevents me from being able to get the correct row I need (ordered by the last message sent from the sender "msgsenttime").
My goal is to make this as efficient as possible on my server and database.
This is what I have right now, not working. (This is a sub-query of another query I use to join relevant information afterwards but I figure that is irrelevant)
SELECT DISTINCT ON ("msgfromid") "msgfromid", "msgid", "msgtoid", "msgsenttime", "msgreadtime", "msgcontent", "msgreportstatus", "senderun", "recipientun"
FROM "messages"
WHERE "msgtoid" = ?
ORDER BY "msgsenttime" desc, "msgfromid"
I thought maybe if I pre-ordered them in a sub-query it would work but it just seems to randomly pick one anyway, and this can't be very efficient, even if it were to work, since I'm pulling every message out to begin with, right?:
SELECT DISTINCT ON ("msgfromid") "msgfromid", "msgid", "msgtoid", "msgsenttime", "msgreadtime", "msgcontent", "msgreportstatus", "senderun", "recipientun"
FROM
(
SELECT * FROM "messages"
WHERE "msgtoid" = ?
ORDER BY "msgsenttime" desc
) as "mqo"
Thanks for any help.
Your order by keys are in the wrong order:
SELECT DISTINCT ON ("msgfromid") m.*
FROM "messages" m
WHERE "msgtoid" = ?
ORDER BY "msgfromid", "msgsenttime" desc;
For DISTINCT ON, the keys in parentheses need to be the first keys in the ORDER BY.
If you want the final result ordered in a different way, then you need to use a subquery, with a different ORDER BY on the outer query.

Jet-SQL to TSQL

In MS Access 2010 I have the following code:
SELECT
[Teile-LF-Beziehungen].Lieferant,
COUNT([Teile-LF-Beziehungen].Lieferant) AS [Anz Teile],
First([Teile-LF-Beziehungen].Name) AS Name
FROM
[Teile-LF-Beziehungen]
GROUP BY
[Teile-LF-Beziehungen].Lieferant
ORDER BY
COUNT([Teile-LF-Beziehungen].Lieferant) DESC;
I want to put that query into SQL Server, because MS Access should be only the frontend.
But in SQL Server I can't use the ORDER in a view. But why? I don't understand it. The code I want to use in SQL Server:
SELECT
[Lieferant],
COUNT([Lieferant]) AS [Anz Teile],
MIN([Name]) AS [Name]
FROM
[dbo].[VIEW_Teile-LF-Beziehungen]
GROUP BY
[Lieferant]
ORDER BY
COUNT([Lieferant]) DESC;
I know it don't work. But is there any way to incur a MS Access query 1:1 to a SQL Server query (view)?
Only the outermost select can use an order by (but you might state a TOP 100 percent to trick this out). Therefore it is perfectly OK, that at VIEW does not allow this.
Many people think, that tables have kind of an implicit order (as you see the result ordered), but this is random... The next call could lead to a different sorting.
There is another way using ROW_NUMBER with OVER(ORDER BY). The result is delivered in this order and the order is guaranteed as long the orderby is sorting after unique values.
EDIT
Sorry my first attempt was to quick. The ROW_NUMBER was not allowed due to the grouping
This should work:
SELECT tbl.Lieferant
,tbl.[Anz Teile]
,tbl.Name
,ROW_NUMBER() OVER(ORDER BY tbl.[Anz Teile] DESC) AS Sort
FROM
(
SELECT [Lieferant]
,COUNT([Lieferant]) AS [Anz Teile]
,MIN([Name]) AS [Name]
FROM [dbo].[VIEW_Teile-LF-Beziehungen]
GROUP BY [Lieferant]
) AS tbl;
EDIT2
This SELECT can be placed within a VIEW, just place your CREATE VIEW YourViewName AS before the SELECT and execute. After this you'll be able to do a SELECT * FROM YourViewName to get a sorted list.
BUT
As stated in many places: The best is the outermost ORDER BY in any case!
ORDER BY doesnt work inside the view. SQL server is free to return the rows anyway he want if you dont include the order by when calling the View
So you need
SELECT *
FROM yourView
ORDER BY yourField
EDIT: Im saying if your view is
CREATE VIEW yourView AS
SELECT
[Lieferant],
COUNT([Lieferant]) AS [Anz Teile],
MIN([Name]) AS [Name]
FROM
[dbo].[VIEW_Teile-LF-Beziehungen]
GROUP BY
[Lieferant];
Then you call your View like this
SELECT *
FROM yourView
ORDER BY [Anz Teile]

SQL pagination when ordering by modified date

I have a bunch of records that I want to paginate by reverse modified date. From what I can tell, using a simple query pulls the same sub-set of records and then sorts only those by date.
Something like this:
SELECT * FROM items WHERE status='1' ORDER BY modified_date DESC LIMIT start,count
Would an index help me? Or am I going to have to figure out some way to code this perhaps adding a column that somehow keeps track of modified_date in reverse order?
An index on (status, modified_date) might help. See indexes dos and donts.
This query looks good for me. It does the following:
Find records with status = 1
Order them by modified_date DESC
Return count records starting from start
So if you need to show first page, you should set start=0. For second page it'll be start=count, for third start=2*count and so on.
Or do you have performance problems with this?
Its a hack and I haven't tried it because I can't reproduce your problem and may not perform well but this may work for you
SELECT *
FROM (SELECT *
FROM items
WHERE status = '1'
ORDER BY modified_date desc ) t
LIMIT START, COUNT
You can add a column that holds a TIMESTAMP then set the auto-update property on it, so that it is properly updated. Finally, create an index for this column. Your query will look something like this:
SELECT *
FROM items
WHERE status='1'
ORDER BY 'timestamp' DESC
LIMIT start,count

SQL Simple ORDER BY

I'm new to SQL and I don't think this question should be hard to answer. I have a high-score table for a game that contains the columns name, score, and rank. I want to know how I can order the table by descending order each time a new score is added so the table can always stay ordered by score.
I know this is the wrong way of doing this, but I hope this makes my point kind of clearer.
UPDATE `HSTable`.`Highscores` ORDER BY `Highscores`.`score` DESC;
What is the correct way of approaching this?
One more thing, is there a way I can set it so that the ranking value always stays where it's suppose to be from the SQL, for example, 1st place is always at the top regardless the score?
generally we use order by while fetching data from table
so we use
SELECT * FROM `HSTable` ORDER BY `score` DESC
Use a ranking function like RANK or DENSE_RANK to rank the results. For better performance you can add a clustered index that starts with score descending.
You can get ordered results using SELECT clause:
SELECT * FROM `HSTable` ORDER BY `score` DESC
I don't believe the order of the data in your database table should really matter because when you query the data you can sort it any which way you would like. What is the reason why you want to have the data stored in the database in the correct order?
That is not the correct way to select records in SQL. Use this instead:
SELECT * FROM `tablename` ORDER BY `id` DESC