[英]Sort the SQL Query in the order of IN
I am writing a query 我正在写一个查询
SELECT * FROM EMPLOYEES WHERE EMP_ID IN (10,5,3,9,2,8,6)
I want the result should be in the following order 我希望结果应按以下顺序排列
Emp_id Emp_Name
10 John
5 Joe
3 Tippu
9 Rich
2 Chad
8 Chris
6 Rose
Basically in the same order of IN Clause. 基本上与IN子句的顺序相同。 Is it possible to do that? 有可能吗? Please let me know. 请告诉我。
PS: I can either do it in SQL or after I get the resultset if I can use LINQ or something to sort in front end option also will work for me (I have the Emp IDs in array in front end) PS:我可以在SQL中执行此操作,也可以在获取结果集后如果我可以使用LINQ或者在前端选项中进行排序选项也适用于我(我在前端有数组中的Emp ID)
Thanks 谢谢
String comment answer; 字符串评论答案; this will give the same result as original answer but matching on strings: 这将给出与原始答案相同但在字符串上匹配的结果:
string orgList = "John,Joe,Tippu,Rich,Chad,Chris,Rose";
List<string> orderArray = new List<string>(orgList.Split(",".ToCharArray()));
// the linq to do the ordering
var result = ourList.OrderBy(e => {
int loc = orderArray.IndexOf(e.Name);
return loc == -1? int.MaxValue: loc;
});
as a side note the original answer would probably had been better with these two lines: 作为旁注,这两行可能会更好:
string orgList = "10,5,3,9,2,8,6";
List<int> orderArray = new List<int>(orgList.Split(",".ToCharArray()));
instead of using integer constants. 而不是使用整数常量。 Using the code above will order by an arbitrary comma separated list of integers. 使用上面的代码将按任意逗号分隔的整数列表排序。
The solution below in Linq gives this result: Linq中的解决方案给出了以下结果:
void Main()
{
// some test data
List<Person> ourList = new List<Person>()
{
new Person() { ID = 1, Name = "Arron" },
new Person() { ID = 2, Name = "Chad" },
new Person() { ID = 3, Name = "Tippu" },
new Person() { ID = 4, Name = "Hogan" },
new Person() { ID = 5, Name = "Joe" },
new Person() { ID = 6, Name = "Rose" },
new Person() { ID = 7, Name = "Bernard" },
new Person() { ID = 8, Name = "Chris" },
new Person() { ID = 9, Name = "Rich" },
new Person() { ID = 10, Name = "John" }
};
// what we will use to order
List<int> orderArray = new List<int>(){10,5,3,9,2,8,6};
// the linq to do the ordering
var result = ourList.OrderBy(e => {
int loc = orderArray.IndexOf(e.ID);
return loc == -1? int.MaxValue: loc;
});
// good way to test using linqpad (get it at linqpad.com
result.Dump();
}
// test class so we have some thing to order
public class Person
{
public int ID { get; set; }
public string Name { get; set; }
}
Original bad SQL answer 原来不好的SQL答案
WITH makeMyOrder
(
SELECT 10 as ID, 1 as Ord
UNION ALL
SELECT 5 as ID, 2 as Ord
UNION ALL
SELECT 3 as ID, 3 as Ord
UNION ALL
SELECT 9 as ID, 4 as Ord
UNION ALL
SELECT 2 as ID, 5 as Ord
UNION ALL
SELECT 8 as ID, 6 as Ord
UNION ALL
SELECT 6 as ID, 7 as Ord
),
SELECT *
FROM EMPLOYEES E
JOIN makeMyOrder O ON E.EMP_ID = O.ID
ORDER BY O.Ord
What, Linq-To-SQL doesn't have a magic button you can press to make it do this? 什么,Linq-To-SQL没有魔术按钮你可以按它来做到这一点? :-) :-)
To do this in SQL Server, you need a function that will turn your list into a set and maintain the order. 要在SQL Server中执行此操作,您需要一个将列表转换为集合并维护订单的函数。 There are many ways to skin this cat; 这种猫的皮肤有很多种方法; here's one: 这是一个:
CREATE FUNCTION dbo.SplitInts_Ordered
(
@List VARCHAR(MAX),
@Delimiter VARCHAR(255)
)
RETURNS TABLE
AS
RETURN (SELECT [Index] = ROW_NUMBER() OVER (ORDER BY Number), Item
FROM (SELECT Number, Item = CONVERT(INT, SUBSTRING(@List, Number,
CHARINDEX(@Delimiter, @List + @Delimiter, Number) - Number))
FROM (SELECT ROW_NUMBER() OVER (ORDER BY [object_id])
FROM sys.all_objects) AS n(Number)
WHERE Number <= CONVERT(INT, LEN(@List))
AND SUBSTRING(@Delimiter + @List, Number, LEN(@Delimiter)) = @Delimiter
) AS y);
GO
Now you can just say: 现在你可以说:
DECLARE @list VARCHAR(MAX);
SET @list = '10,5,3,9,2,8,6';
SELECT e.Emp_Id, e.Emp_Name -- never use * in production code
FROM dbo.Employees AS e -- always use schema prefix
INNER JOIN dbo.SplitInts_Ordered(@list, ',') AS x
ON x.Item = e.Emp_Id
ORDER BY x.[Index];
A much, much, much, much, much better approach is to stop passing a comma-separated list at all, and use Table-Valued Parameters. 一个更多,更多,更好,更好的方法是停止传递逗号分隔列表,并使用表值参数。 This is a set of things, not a string or some JSON obscenity. 这是一组东西,不是字符串或一些JSON淫秽。 Create a DataTable in your C# code, with two columns, the list and the order. 在C#代码中创建一个DataTable,包含两列,列表和顺序。 Then create a table type: 然后创建一个表类型:
CREATE TYPE dbo.SortedList AS TABLE(ID INT, [Order] INT);
Then a stored procedure that takes this as a parameter: 然后是一个以此为参数的存储过程:
CREATE PROCEDURE dbo.GetTheList
@x dbo.SortedList READONLY
AS
BEGIN
SET NOCOUNT ON;
SELECT e.Emp_Id, e.Emp_Name
FROM dbo.Employees AS e
INNER JOIN @x AS x
ON x.ID = e.Emp_Id
ORDER BY x.[Order];
END
GO
Whether you can do this with Linq-To-SQL, I'm not sure; 你是否可以用Linq-To-SQL做到这一点,我不确定; people seem to jump on the Linq bandwagon very quickly, because it makes things so easy. 人们似乎很快就跳上了Linq的潮流,因为它让事情变得如此简单。 Well, as long as you don't need to actually do anything. 好吧,只要你不需要实际做任何事情。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.