在两个单独的 SQL 表上计算总数
Counting totals on two separate SQL tables
我有两个(相同的)表
待办事项
ItemBatch | Item
abc Pickup sticks
abc Tie my shoe
xyz Suck my thumb
abc Climb a tree
完成列表
ItemBatch | Item
abc Tie my shoe
我试图从每个 [ItemBatch] 中的每一个中获取一个计数,但不确定在一个查询中是否真的可行?
单独做
select count(*) from ToDoList where ItemBatch = 'abc' /* repeat for each ItemBatch */
select count(*) from DoneList where ItemBatch = 'abc' /* repeat for each ItemBatch */
并在前端分配给变量,这样我就可以获得以下内容:
ItemBatch | Total | DoneList | DoneList - ToDoList
abc 3 1 2
xyz 1 0 1
有没有一个查询可以一下子给我完整的输出?我尝试加入初学者
select count(cc.[ItemBatch]), count(cq.[ItemBatch])
from ToDoList cc
left join DoneList cq on cc.[ItemBatch] = cq.[ItemBatch]
很快意识到这行不通...
然后我想
select
(select count(*) from ToDoList where [ItemBatch] = 'abc' ) as Total,
(select count(*) from DoneList where [ItemBatch] = 'abc' ) as DoneList
但我无法弄清楚如何一次性为每个 ItemBatch
输出所有行,group by
不适用于最后一个语句:
select
(select [ItemBatch], count([ItemBatch]) from ToDoList group by [ItemBatch) as Total,
(select [ItemBatch], count([ItemBatch]) from DoneList group by [ItemBatch]) as DoneList
如果您使用正确的 JOIN
条件,您的 LEFT JOIN
方法将起作用:
select count(cc.[ItemBatch]), count(cq.[ItemBatch])
from ToDoList cc left join
DoneList cq
on cc.[ItemBatch] = cq.[ItemBatch] AND cc.Item = cq.Item;
每 ItemBatch
你会添加一个 GROUP BY
:
select ItemBatch, count(*), count(cq.ItemBatch)
from ToDoList cc left join
DoneList cq
on cc.ItemBatch = cq.ItemBatch AND cc.Item = cq.Item
group by cc.ItemBatch
由于 SELECT
语句中的计算,您应该尝试在您的案例中使用 OUTER APPLY
。
The OUTER APPLY operator returns all the rows from the left table
expression irrespective of its match with the right table expression.
For those rows for which there are no corresponding matches in the
right table expression, it contains NULL values in columns of the
right table expression.
所以,你的声明应该是:
SELECT
cc.ItemBatch,
COUNT(*) as Total,
ISNULL(dl.DoneListTotal, 0) as DoneList,
COUNT(*) - ISNULL(dl.DoneListTotal, 0) as [DoneList - ToDoList]
FROM ToDoList cc
OUTER APPLY (SELECT COUNT(*) DoneListTotal
FROM DoneList cq
WHERE cc.ItemBatch = cq.ItemBatch) dl
GROUP BY cc.ItemBatch, dl.DoneListTotal;
使用 UNION ALL
获取 2 个 table 的所有 ItemBatch
,另外还有 2 个列 ToDo
和 Done
来指示哪个 table 他们属于并聚合:
SELECT ItemBatch,
SUM(Todo) ToDo,
SUM(Done) Done,
SUM(Todo) - SUM(Done) Difference
FROM (
SELECT ItemBatch, 1 ToDo, 0 Done FROM ToDoList
UNION ALL
SELECT ItemBatch, 0, 1 FROM DoneList
) t
GROUP BY ItemBatch
参见demo。
结果:
> ItemBatch | ToDo | Done | Difference
> :-------- | ---: | ---: | ---------:
> abc | 3 | 1 | 2
> xyz | 1 | 0 | 1
我有两个(相同的)表
待办事项
ItemBatch | Item
abc Pickup sticks
abc Tie my shoe
xyz Suck my thumb
abc Climb a tree
完成列表
ItemBatch | Item
abc Tie my shoe
我试图从每个 [ItemBatch] 中的每一个中获取一个计数,但不确定在一个查询中是否真的可行?
单独做
select count(*) from ToDoList where ItemBatch = 'abc' /* repeat for each ItemBatch */
select count(*) from DoneList where ItemBatch = 'abc' /* repeat for each ItemBatch */
并在前端分配给变量,这样我就可以获得以下内容:
ItemBatch | Total | DoneList | DoneList - ToDoList
abc 3 1 2
xyz 1 0 1
有没有一个查询可以一下子给我完整的输出?我尝试加入初学者
select count(cc.[ItemBatch]), count(cq.[ItemBatch])
from ToDoList cc
left join DoneList cq on cc.[ItemBatch] = cq.[ItemBatch]
很快意识到这行不通...
然后我想
select
(select count(*) from ToDoList where [ItemBatch] = 'abc' ) as Total,
(select count(*) from DoneList where [ItemBatch] = 'abc' ) as DoneList
但我无法弄清楚如何一次性为每个 ItemBatch
输出所有行,group by
不适用于最后一个语句:
select
(select [ItemBatch], count([ItemBatch]) from ToDoList group by [ItemBatch) as Total,
(select [ItemBatch], count([ItemBatch]) from DoneList group by [ItemBatch]) as DoneList
如果您使用正确的 JOIN
条件,您的 LEFT JOIN
方法将起作用:
select count(cc.[ItemBatch]), count(cq.[ItemBatch])
from ToDoList cc left join
DoneList cq
on cc.[ItemBatch] = cq.[ItemBatch] AND cc.Item = cq.Item;
每 ItemBatch
你会添加一个 GROUP BY
:
select ItemBatch, count(*), count(cq.ItemBatch)
from ToDoList cc left join
DoneList cq
on cc.ItemBatch = cq.ItemBatch AND cc.Item = cq.Item
group by cc.ItemBatch
由于 SELECT
语句中的计算,您应该尝试在您的案例中使用 OUTER APPLY
。
The OUTER APPLY operator returns all the rows from the left table expression irrespective of its match with the right table expression. For those rows for which there are no corresponding matches in the right table expression, it contains NULL values in columns of the right table expression.
所以,你的声明应该是:
SELECT
cc.ItemBatch,
COUNT(*) as Total,
ISNULL(dl.DoneListTotal, 0) as DoneList,
COUNT(*) - ISNULL(dl.DoneListTotal, 0) as [DoneList - ToDoList]
FROM ToDoList cc
OUTER APPLY (SELECT COUNT(*) DoneListTotal
FROM DoneList cq
WHERE cc.ItemBatch = cq.ItemBatch) dl
GROUP BY cc.ItemBatch, dl.DoneListTotal;
使用 UNION ALL
获取 2 个 table 的所有 ItemBatch
,另外还有 2 个列 ToDo
和 Done
来指示哪个 table 他们属于并聚合:
SELECT ItemBatch,
SUM(Todo) ToDo,
SUM(Done) Done,
SUM(Todo) - SUM(Done) Difference
FROM (
SELECT ItemBatch, 1 ToDo, 0 Done FROM ToDoList
UNION ALL
SELECT ItemBatch, 0, 1 FROM DoneList
) t
GROUP BY ItemBatch
参见demo。
结果:
> ItemBatch | ToDo | Done | Difference
> :-------- | ---: | ---: | ---------:
> abc | 3 | 1 | 2
> xyz | 1 | 0 | 1