Sql 子查询中的“订单依据”

Sql 子查询中的“订单依据”,sql,sql-server,sql-order-by,union,Sql,Sql Server,Sql Order By,Union,我试着选择在9-12年级每一个年级中最和善的学生。我在sql server 2012中编写了以下代码,以使学生拥有最多的时间: (select top 1 stu_first, stu_last, sum(KIND_hours) as total from STUDENT inner join KIND on student.stu_id=KIND.stu_id where (12-(STU_CLASS_OF-2014))=9 group by stu_first, stu_last orde

我试着选择在9-12年级每一个年级中最和善的学生。我在sql server 2012中编写了以下代码,以使学生拥有最多的时间:

(select top 1  stu_first, stu_last, sum(KIND_hours) as total from STUDENT inner join KIND
on student.stu_id=KIND.stu_id
where (12-(STU_CLASS_OF-2014))=9
group by stu_first, stu_last
order by total desc)
这段代码是有效的,但是当我尝试将代码合并为两个等级时,我得到了一个错误:关键字“order”附近的语法不正确。 我的密码在这里

(select top 1  stu_first, stu_last, sum(KIND_hours) as total from STUDENT inner join KIND
on student.stu_id=KIND.stu_id
where (12-(STU_CLASS_OF-2014))=9
group by stu_first, stu_last
order by total desc)
union
(select top 1  stu_first, stu_last, sum(KIND_hours) as total from STUDENT inner join KIND
on student.stu_id=KIND.stu_id
where (12-(STU_CLASS_OF-2014))=10
group by stu_first, stu_last
order by total desc)

stu_class_of是学生毕业的那一年

你的工会不应该是两个子选区。您需要删除其中的一个ORDER BY:

DECLARE @T1 TABLE (Id INT);
INSERT INTO @T1 VALUES (1), (2), (3);

DECLARE @T2 TABLE (Id INT);
INSERT INTO @T1 VALUES (7), (9), (-1);


SELECT * FROM @T1
UNION
SELECT * FROM @T2
ORDER BY Id DESC;


/* Output:
9 --From @T2
7 --From @T2
3
2
1
-1 --From @T2
*/
编辑:我现在意识到你真正想要的是什么。我应该通过看到你的前1名和一个工会结合而意识到这一点。实际上,您需要的是一个CTE公共表表达式。以下是您要查找的查询:

/*
SET IDENTITY_INSERT [STUDENT] ON;
INSERT INTO [STUDENT] (stu_id, stu_first, stu_last, STU_CLASS_OF) VALUES
(1,  'Leonard', 'Hofstadter', 1989),
(2, 'Sheldon', 'Cooper', 1989),
(3, 'Howard', 'Wolowitz', 1989),
(4, 'Raj', 'Koothrappali', 1989),
(5, 'Penny', '?', 2001),
(6, 'Bernadette', 'Rostenkowski ', 2001),
(7, 'Amy', 'Fowler', 2001)
SET IDENTITY_INSERT [STUDENT] OFF;

SET IDENTITY_INSERT [KIND] ON;
INSERT INTO [KIND] (stu_id, [hours]) VALUES
(1,  10),
(2, 13),
(3, 7),
(4, 54),
(5, 78),
(6, 13),
(7, 64)
SET IDENTITY_INSERT [KIND] OFF;
*/

WITH CTE AS (
    SELECT ROW_NUMBER() OVER (PARTITION BY [STU_CLASS_OF] ORDER BY SUM([KIND].[hours]) DESC) AS [RowNumber],
        [stu_first],
        [stu_last],
        SUM([KIND].[hours]) AS [total]
    FROM [STUDENT]
        INNER JOIN [KIND] ON [STUDENT].[stu_id] = [KIND].[stu_id]
    GROUP BY [stu_first], [stu_last], [STU_CLASS_OF]
)
SELECT
    [stu_first],
    [stu_last],
    [total]
FROM CTE
WHERE RowNumber = 1
ORDER BY [STU_CLASS_OF] DESC;
以下是对幕后实际情况的简短解释: CTE就像一个子选择,但它有很多很棒的特性。其中一个是ROW_NUMBER,它在每次看到您在{something}分区中写入的内容时都会给出一个ID

但如果它是随机的,你每次都会得到不同的结果。因此,您还向它添加了orderby,以便它知道哪些应该获得最低的ID。 在这种情况下,我们每个班只有一个学生。所以我加入了[学生班]。但你也只想从每个人的头一个。所以我按[total]DESC订购

如果您希望每个类中的前3名而不是前1名,则只需将WHERE RowNumber=1改为3即可

如果您只需要某些特定类的数据,而不是像我一样需要每个类的数据,那么只需将前面的WHERE子句添加到最终的SELECT中,如下所示:

WHERE RowNumber = 1
    AND (12 - ([STU_CLASS_OF] - 2014)) = 9
    AND (12 - ([STU_CLASS_OF] - 2014)) = 10
select * from 
(select * from xx order by x) x
试试这个:

SELECT * FROM
(SELECT TOP 1 stu_first, stu_last, SUM(kind_hours) AS total 
 FROM student
 INNER JOIN kind ON student.stu_id = kind.stu_id
 WHERE (12-(stu_class_of-2014)) = 9
 GROUP BY stu_first, stu_last
 ORDER BY total DESC)

UNION

SELECT * FROM
(SELECT TOP 1 stu_first, stu_last, SUM(kind_hours) AS total 
 FROM student
 INNER JOIN kind ON student.stu_id = kind.stu_id
 WHERE (12-(stu_class_of-2014)) = 10
 GROUP BY stu_first, stu_last
 ORDER BY total DESC)
进行2个查询..派生表。以下是一个有效的Northwind示例:

  Use Northwind
     GO

Select  OrderID , CustomerID , EmployeeID from 
( Select TOP 1 OrderID , CustomerID , EmployeeID from  dbo.Orders where ShipCountry='France' Order by ShippedDate )
as derived1
UNION ALL
Select  OrderID , CustomerID , EmployeeID from 
( Select TOP 1 OrderID , CustomerID , EmployeeID from  dbo.Orders where ShipCountry='Germany' Order by ShippedDate  )
as derived2
这里插入了您的查询,但我无法测试它们,因为我没有您的DDL

    Select  * from 
    ( select top 1  stu_first, stu_last, sum(KIND_hours) as total from STUDENT inner join KIND
on student.stu_id=KIND.stu_id
where (12-(STU_CLASS_OF-2014))=9
group by stu_first, stu_last
order by total desc )
    as derived1
    UNION ALL
    Select  * from 
    ( select top 1  stu_first, stu_last, sum(KIND_hours) as total from STUDENT inner join KIND
on student.stu_id=KIND.stu_id
where (12-(STU_CLASS_OF-2014))=10
group by stu_first, stu_last
order by total desc  )
    as derived2
可能的解决方法的老答案

如果需要区分两组数据的顺序,可以使用以下技巧:

IF OBJECT_ID('tempdb..#TableOne') IS NOT NULL
begin
        drop table #TableOne
end



IF OBJECT_ID('tempdb..#TableTwo') IS NOT NULL
begin
        drop table #TableTwo
end



CREATE TABLE #TableOne
( 
SurrogateKeyIDENTITY int not null IDENTITY (1,1) , 
NameOfOne varchar(12)
)



CREATE TABLE #TableTwo
( 
SurrogateKeyIDENTITY int not null IDENTITY (1,1) , 
NameOfTwo varchar(12)
)


Insert into #TableOne (NameOfOne)
Select 'C' as Alpha UNION ALL Select 'B' as Alpha UNION ALL Select 'D' as Alpha UNION ALL Select 'Z' as Alpha


Insert into #TableTwo (NameOfTwo)
Select 'T' as Alpha UNION ALL Select 'W' as Alpha UNION ALL Select 'X' as Alpha UNION ALL Select 'A' as Alpha



select 1 , NameOfOne from #TableOne
UNION
select 2 , NameOfTwo from #TableTwo
Order by 1 , 2 /* These are the "Ordinal Positions of the Column*/




IF OBJECT_ID('tempdb..#TableOne') IS NOT NULL
begin
        drop table #TableOne
end


IF OBJECT_ID('tempdb..#TableTwo') IS NOT NULL
begin
        drop table #TableTwo
end
使用UNION时,不能在子查询中使用ORDER BY。我相信有更好的解决方案,但将子查询包装到另一个级别将对您有效。试试这个:

SELECT * FROM
(SELECT TOP 1 stu_first, stu_last, SUM(kind_hours) AS total 
 FROM student
 INNER JOIN kind ON student.stu_id = kind.stu_id
 WHERE (12-(stu_class_of-2014)) = 9
 GROUP BY stu_first, stu_last
 ORDER BY total DESC)

UNION

SELECT * FROM
(SELECT TOP 1 stu_first, stu_last, SUM(kind_hours) AS total 
 FROM student
 INNER JOIN kind ON student.stu_id = kind.stu_id
 WHERE (12-(stu_class_of-2014)) = 10
 GROUP BY stu_first, stu_last
 ORDER BY total DESC)

每次我想对子查询进行排序时,我倾向于将其包装在外部查询中,如下所示:

WHERE RowNumber = 1
    AND (12 - ([STU_CLASS_OF] - 2014)) = 9
    AND (12 - ([STU_CLASS_OF] - 2014)) = 10
select * from 
(select * from xx order by x) x

通过这种方式,您可以在联合或任何其他情况下嵌入此查询,并且由于您在内部查询中应用了排序,因此它将始终有效

Order By子句不能在子查询中使用。您可以在子查询中使用Order By,例如:选择缺勤。abs_日期,12-stu_class_of-2014作为成绩,将缺勤.abs_日期计算为学生内部缺勤的总计。STU_ID=缺勤.STU_ID,其中缺勤.abs_日期在选择前5名缺勤中。abs_日期按abs_日期从缺勤组按abs_日期按count排序缺勤。abs_日期按abs_日期描述组,按abs_日期排序,totalyes您可以在子查询中与TOP子句一起排序。@ThitLwinOo当然可以,为什么不可以?ORDERBY通常用于子查询,以选择数据库中的第一个/最后一个记录,其中包括TOP、first/last、LIMIT等。。。不可用。如果我删除其中一个order by,则会得到不正确的数据。您还需要删除括号。不要试图合并2个子选择项。照我做的做。只需选择两个不同的选项,然后在它们之间写UNION。没有括号。但这实际上是除重点之外的,真的。因为你甚至不需要工会。只要修改你的WHERE子句,比如@Racil Hilan的更新答案。我试过这个,但是当我把11和11年级的学生分为两个时,我给了两个来自同一年级的学生12@user3499265是的,我贴了之后注意到了。我已经更新了我的答案,您现在可以试试。我不明白您的建议是什么,如果您需要第一个查询中的前1项…在第二个查询中显示在前1项之前…您可以使用这个技巧,将1或2作为第一列的值。我不明白您的技巧是如何工作的,你能解释一下吗?运行我的查询。问问自己为什么“Z”出现在结果集中的第四行,而不是最后一行。我在这个回答的顶部添加了一个新的答案。衍生