正如您在 ER 图表的链接中所见,我有两个表,Department
和 Admissions
。我的目标是仅打印出具有最多 Department
的 Admissions
的 Reshnum。
我的第一次尝试是这样的:
select top 1 count(*) as Number_of_Adm, Department.ReshNum
from Admission
inner join Department on Admission.DepartmentId = Department.id
group by Department.ReshNum
order by Number_of_Adm;
它非常简单,计算行数,将它们分组到部门,并在订购最高计数后打印出最高答案。我的问题是它同时打印计数和 Rashnum。
我试图只打印 Rashnum(分支名称/序列号)。我已经阅读了子查询以尝试获取子查询中的计数,然后从该查询中选择分支,但我无法让它工作。
有什么建议吗?
答案 0 :(得分:2)
您只需要选择您需要的列并将 count
移动到 order by
条件。
使用列别名还有助于使您的查询更容易理解,尤其是当查询中有更多的列和表时。
你还说你最想要,我想你需要降序排列。
select top (1) d.ReshNum
from Admission a
inner join Department d
on a.DepartmentId = d.id
group by d.ReshNum
Order By count(*) desc;
答案 1 :(得分:0)
好问题! Stu's answer 可能是最佳方式,具体取决于您的索引。
仅供后代使用,因为您的查询包括如何使子查询工作,这里是使用子查询的替代方法。据我所知,至少在我的数据库上,SQL Query Optimizer 计划这两个查询在任一版本上的性能大致相同。
子查询在大量场景中非常有用,例如当您想添加另一个字段以显示和分组而不必在组中的表上添加每个其他字段时by 子句。
SELECT TOP 1 x.ReshNum /*, x.DepartmentName*/
FROM
(
SELECT count(*) AS CountOfAdmissions, d.CustomerNumber /*d.DepartmentName*/
FROM Adminssion a
INNER JOIN Department d ON a.DepartmentId= d.Id
GROUP BY d.ReshNum /*, d.DepartmentName*/
/*HAVING count(*) > 50*/
) x
ORDER BY CountOfAdmissions DESC
工作原理:
您需要将子查询括在括号中并为该子查询指定别名。上面,我将它别名为 x
就在右括号之外作为任意标识符。您当然可以将其别名为 depts
或 mySubQuery
或任何在结果整体查询中读取良好的内容。
接下来,需要注意的是,虽然 group by 子句可以包含在子查询中,但 order by 子句不能。所以你必须在查询的外部保留 order by 子句,这意味着你实际上是在对子查询的结果进行排序,而不是对实际表的结果进行排序。这可能对性能很有帮助,因为您的子查询的结果可能比整个表小得多。但是,它不会以这种方式使用您的表的索引,因此根据您的索引的方式,这种奖励可能会消失,甚至比没有子查询的排序更糟糕。
最后,这种子查询方法的好处之一是,如果您愿意,您可以轻松地添加另一个字段,例如部门名称,而不会降低性能。上面我在 /*
和 */
标志之间注释掉了假设的部门名称字段。请注意,它在子查询内部使用 d
表别名 引用,但使用了子查询的 x
别名 em> 在子查询之外。
作为奖励,万一它出现,上面也注释掉了一个 sharing 子句,您可能可以使用它。只是为了显示可以在子查询中执行的操作。
干杯