我是一位试图将某些东西移植到MS SQL Server的MySQL用户。
我正在加入几个表,并通过GROUP BY聚合一些列。
一个简单的例子是员工和项目:
select empID, fname, lname, title, dept, count(projectID)
from employees E left join projects P on E.empID = P.projLeader
group by empID
...这可以在MySQL中运行,但MS SQL更严格,要求所有内容都包含在聚合函数中,或者是GROUP BY子句的一部分。
因此,当然,在这个简单的例子中,我假设我可以在group by子句中包含额外的列。但我正在处理的实际查询非常复杂,并且包括在一些非聚合列上执行的一系列操作...即,尝试将所有这些操作包含在group by子句中会非常难看
那么有更好的方法吗?
答案 0 :(得分:16)
你可以使用这些内容来解决这些问题:
select e.empID, fname, lname, title, dept, projectIDCount
from
(
select empID, count(projectID) as projectIDCount
from employees E left join projects P on E.empID = P.projLeader
group by empID
) idList
inner join employees e on idList.empID = e.empID
这样您可以通过操作避免额外的组,并且您可以获得所需的任何数据。此外,您有更好的机会在某些情况下充分利用索引(如果您没有返回完整信息),并且可以更好地与分页相结合。
答案 1 :(得分:4)
“尝试将所有这些内容包含在group by子句中会非常难看。”
是的 - 这是唯一的方法* - 只需将非聚合列复制并粘贴到group by子句中,删除别名,这样就可以了......
*你可以将它包装在一个嵌套的SELECT中,但这可能就像丑陋......
答案 2 :(得分:2)
MySQL不常见 - 并且在技术上不符合SQL标准 - 允许您省略GROUP BY子句中的项目。在标准SQL中,select-list中的每个非聚合列必须在GROUP BY子句中完整列出(通过名称或序号,但不推荐使用)。
(哦,虽然MySQL很不寻常,但它允许速记很好。)
答案 3 :(得分:1)
您不需要加入子查询,因为没有必要根据员工的empID进行分组 - 您可以在项目的projectLeader字段中执行此操作。
通过内部联接(如我所说),您将获得至少拥有一个项目的员工列表。如果您想要所有员工的列表,只需将其更改为左连接
select e.empID, e.fname, e.lname, e.title, e.dept, p.projectIDCount
from employees e
inner join ( select projLeader, count(*) as projectIDCount
from projects
group by projLeader
) p on p.projLeader = e.empID
答案 4 :(得分:1)
我将假设empID
是结果联接语句中的唯一ID。在这种情况下,您可以使用distinct
获得相同的结果。
select distinct empID, fname, lname, title, dept, count(projectID)
from employees E
left join projects P on E.empID = P.projLeader
答案 5 :(得分:0)
select子句中的子查询也可能是合适的。它适用于给出的示例,但可能不适用于您正在处理的实际复杂查询。
select
e.empID, fname, lname, title, dept
, (select count(*) from projects p where p.projLeader = e.empId) as projectCount
from
from employees E