如何重新编写此查询,以便它不会触发以下错误:
"无法对包含聚合或子查询的表达式执行聚合函数。"
SELECT
employees.loc_id
,SUM(CASE
WHEN
pos IN (SELECT DISTINCT pos FROM lookup WHERE lbl='Staff')
AND
loc IN (SELECT DISTINCT loc FROM lookup WHERE lbl='Staff')
THEN 1
ELSE 0
END) AS 'Staff Site 1'
,SUM(CASE
WHEN
pos IN (SELECT DISTINCT pos FROM table WHERE lbl='Staff')
AND
loc IN (SELECT DISTINCT loc FROM table WHERE lbl='Staff')
THEN 1
ELSE 0
END) AS 'Staff Site 2'
FROM table GROUP BY table.key_id ORDER BY key_id
显然我不能在SELECT
内添加SUM
声明?我怎样才能确保我只针对上述代码中描述的情况求和?
pos
确定位置的类型。 loc
确定在哪个站点(位置)。查找表的结构如下:
pos | loc | lbl
123 | XYZ | Staff Site 1
456 | XYZ | Staff Site 1
987 | XYZ | Supervisor Site 1
123 | ABC | Staff Site 2
123 | JKL | Staff Site 3
123 | OPQ | Staff Site 4
456 | OPQ | Staff Site 4
345 | OPQ | Staff Site 4
此查找表仅确定与特定位置的位置关联的标签。
有一个员工表,每个员工都被分配了一个pos#。
所以我希望我的查询从employee表中选择所有loc_id
(位置id),并且对于每个loc_id
,对查找表中的每个相应条目求和
因此,如果我有30名员工loc_id=XYZ
与pos=123
和20名员工loc_id=XYZ
与pos=456
,则输出
loc_id | Staff Site 1
XYZ | 50
提前致谢,我希望这不会太令人困惑......
答案 0 :(得分:4)
没有进入能够在聚合函数内部进行SELECT的技术。让我们退后一步,重新考虑您的查询。您正试图通过聚合Lookup表来解决它,但聚合实际上在Employee表上,并且来自查找表的连接。
您似乎也在尝试进行条件聚合以PIVOT结果。但是,无论哪种情况,如果您执行以下操作,您将获得指定的结果,如果您执行以下操作:
SELECT
l.loc
,COUNT(DISTINCT e.Id) as EmployeesAtStaffSite1
FROM
Lookup l
INNER JOIN Employees e
ON e.loc = l.loc
AND e.pos = l.pos
WHERE
l.lbl = 'Staff Site 1'
GROUP BY
l.loc
另请注意,如果您将INNER JOIN更改为LEFT JOIN,那么对于员工站点1的任何未分配员工的位置,您可以获得0计数。
答案 1 :(得分:1)
外部查询引用表名table
,但SELECT列表中的列使用employees.
限定。查询执行GROUP BY table.key_id
,但SELECT列表中返回的列名为loc_id
。这两个子查询都在查找lbl
与文字' Staff'匹配,这是第一个名为lookup
的查找表。我们在lookup
表中没有看到任何示例行,其中该条件将评估为true。在第二个集合中,子查询引用了另一个表(不幸名为)table
。
很难说出你实际上想要通过该查询完成什么。
令人困惑的是,问题的最后一部分表明您希望结果集具有两列,即employee表中的loc_id
的不同值。还有某种聚合列包含满足某些条件的行数......
loc_id Staff Site 1
------ ------------
XYZ 50
让我们备份几步。
看起来您想要查看employee
表中的所有行,而您只关注表中的三列或四列。这是您要分析的行和列集。 (目前尚不清楚是否需要从lbl
表中引用名为table
的列。一组引用table
而不是lookup
的子查询让它看起来就是这样。
因此,从您希望查询查看的行集开始......
SELECT e.loc_id
, e.pos
, e.loc
FROM employee e
由此,您希望获得loc_id
的不同值。您将通过添加GROUP BY子句来实现这一目标。
我们很容易得到一个"计数"使用聚合loc_id
与每个COUNT(*)
相关的员工中的所有行。但是你有兴趣只计算符合特定标准的员工......有条件的聚合。
如果(loc_id,pos)
的组合在查找表中是UNIQUE。 (示例数据使其看起来像是,但我们无法通过有限示例数据中的反例来确定...)
如果它是唯一的,我们可以对该表执行JOIN操作,以及#34;查找"与每位员工lbl
相关联的(loc_id,pos)
。
SELECT e.loc_id
, e.pos
, e.loc
, l.lbl
FROM employee e
LEFT
JOIN lookup l
ON l.loc_id = e.loc_id
AND l.pos = e.pos
如果我想计算某个位置的员工人数与lookup
中lbl
值为Staff Site 1
的行相关联,我倾向于写一下如...
SELECT e.loc_id
, SUM(CASE WHEN l.lbl = 'Staff Site 1' THEN 1 ELSE 0 END) AS [Staff Site 1]
FROM employee e
LEFT
JOIN lookup l
ON l.loc_id = e.loc_id
AND l.pos = e.pos
GROUP BY e.loc_id
ORDER BY e.loc_id
如果我想要第二列,那么计算一下'员工网站2'
SELECT e.loc_id
, SUM(CASE WHEN l.lbl = 'Staff Site 1' THEN 1 ELSE 0 END) AS [Staff Site 1]
, SUM(CASE WHEN l.lbl = 'Staff Site 2' THEN 1 ELSE 0 END) AS [Staff Site 2]
FROM employee e
LEFT
JOIN lookup l
ON l.loc_id = e.loc_id
AND l.pos = e.pos
GROUP BY e.loc_id
ORDER BY e.loc_id
如果我没有特定需要" pivot"结果,我可以更简单地为给定lbl
的每employee
个loc_id
的每个值运行一个返回单独行的查询。
SELECT e.loc_id AS loc_id
, e.lbl AS lbl
, SUM(1) AS cnt
FROM employee e
LEFT
JOIN lookup l
ON l.loc_id = e.loc_id
AND l.pos = e.pos
GROUP BY e.loc_id
ORDER BY e.loc_id
答案 2 :(得分:0)
执行此操作的一种方法(假设您确实需要这样做)是将聚合放在外部查询中,包含条件内容(即子查询),如下所示:
select key_id, sum(staff_site_1) as staff_site_1, , sum(staff_site_2) as staff_site_2
from (
SELECT
employees.key_id
,CASE
WHEN
pos IN (SELECT DISTINCT pos FROM lookup WHERE lbl='Staff')
AND
loc IN (SELECT DISTINCT loc FROM lookup WHERE lbl='Staff')
THEN 1
ELSE 0
END AS staff_site_1
,CASE
WHEN
pos IN (SELECT DISTINCT pos FROM lookup WHERE lbl='Staff')
AND
loc IN (SELECT DISTINCT loc FROM lookup WHERE lbl='Staff')
THEN 1
ELSE 0
END AS staff_site_2
FROM table
) x
GROUP BY key_id
ORDER BY key_id
答案 3 :(得分:0)
; with _CTE as (
SELECT
employees.loc_id
,CASE
WHEN
pos IN (SELECT DISTINCT pos FROM lookup WHERE lbl='Staff')
AND
loc IN (SELECT DISTINCT loc FROM lookup WHERE lbl='Staff')
THEN 1
ELSE 0
END AS StaffSite1
,CASE
WHEN
pos IN (SELECT DISTINCT pos FROM table WHERE lbl='Staff')
AND
loc IN (SELECT DISTINCT loc FROM table WHERE lbl='Staff')
THEN 1
ELSE 0
END AS StaffSite2
FROM table
)
SELECT
loc_id
,SUM(StaffSite1) AS 'Staff Site 1'
,SUM(StaffSite2) AS 'Staff Site 2'
FROM _CTE GROUP BY loc_id ORDER BY loc_id
说明: _CTE是临时结果集,此处将CASE条件应用于数据。然后,您将在此结果集上运行聚合函数。
答案 4 :(得分:0)
我没有看到你在employees.loc_id
的任何地方,但它在选择中。相反,您只有GROUP BY table.key_id ORDER BY key_id