我知道我们不能在group by子句中使用子查询。试图了解它是如何工作的。
如果有2个表dept和dept_code,我正在查看dept代码的工资总和。
假设我选择使用子查询而不是连接。
create table #dept (id int,name varchar(10),salary int)
create table #dept_codes (id int,name varchar(10),code varchar(10))
insert into #dept values (1,'HR',100)
insert into #dept values (2,'IT',500)
insert into #dept values (3,'HR',1500)
insert into #dept values (4,'HR',200)
insert into #dept values (5,'MAR',1200)
insert into #dept_codes values (1,'HR','XX')
insert into #dept_codes values (2,'IT','XXY')
insert into #dept_codes values (3,'MAR','XXYZ')
我要提出的问题是:
select (select code from #dept_Codes b where b.name = a.name) as code
,sum(salary) as salary
from #dept a
group by a.name
输出是:
code salary
XX 1800
XXY 500
XXYZ 1200
我试图了解这是如何工作的。如果我在子查询中有2个连接条件,我是否在group by子句中给出两个列?
对于在select中使用子查询的所有情况,查询是否为真?
答案 0 :(得分:0)
您必须在group by
中指定两列,是的。您在外部表格中引用的所有列(示例中为#dept a
)必须是sum()
之类的聚合函数,或者包含在group by
中。
这也扩展到相关子查询中外表的列。如果您要将and a.id = b.id
添加到子查询中,则会抛出错误
Msg 8120, Level 16, State 1, Line 19
Column '#dept.id' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
答案 1 :(得分:0)
是的,正如Xedni指出你需要GROUP BY中的两个列。我建议使用JOIN,只是为了便于阅读。
SELECT a.name,code,SUM(salary) AS salary
FROM #dept a
INNER JOIN #dept_codes b ON a.name=b.name
GROUP BY a.name,code
或者,如果您不想在结果中使用名称(您仍然需要GROUP BY中的两个列):
SELECT code,SUM(salary) AS salary
FROM #dept a
INNER JOIN #dept_codes b ON a.name=b.name
GROUP BY a.name,code
答案 2 :(得分:0)
当您应用“分组依据”时,您不必选择“分组依据”中的列。 因此,您可以轻松编写。
select sum(salary) as salary
from #dept a
group by a.name
并得到了
salary 1800 500 1200
现在您可以添加子查询
select (select TOP(1) code from #dept_Codes b ) AS Code
,sum(salary) as salary
from #dept a
group by a.name
code salary XX 1800 XX 500 XX 1200
此时,我们的子查询的值不以任何方式绑定到该行。所以它可能总会给你相同的价值(不保证)。
从这一点开始,您可以根据名称链接表格并获取查询。
select (select TOP(1) code from #dept_Codes b where b.name = a.name ) AS Code
,sum(salary) as salary
from #dept a
group by a.name
注意TOP(1)是重要的。
那么你必须在“group by”中添加第二列吗?也许
你可以在下面的语句中运行它会运行得很好,但是如果你想通过聚合函数得到a.id的实际值而不是值,它将需要成为group by的一部分。
select (select TOP(1) code from #dept_Codes b where b.name = a.name and b.id = MIN(a.id) ) AS Code
,sum(salary) as salary
from #dept a
group by a.name
Code salary XX 1800 XXY 500 NULL 1200
至于你的第二个问题。如果查看上表,可以看到最后一个代码为NULL。子查询被评估为空,所以我们得到了一个NULL。 这是因为代码MAR在dept表中的id只有5,MIN(a.id)将是3。