我有三张桌子:
CREATE TABLE person
(id int,
name char(50))
CREATE TABLE eventtype
(id int,
description char(50))
CREATE TABLE event
(person_id int,
eventtype_id int,
duration int)
我想要的是一个查询,它给出了每个人的每个事件类型的总持续时间列表,包括所有零条目。例如。如果有10个人和15个不同的事件类型,则应该返回150行,而不管事件表的内容如何。
我可以在两个表之间使用外连接(例如,所有事件类型的持续时间),但不能使用第二个外连接。
谢谢!
答案 0 :(得分:2)
您必须在混音中添加CROSS APPLY才能获得不存在的关系。
SELECT q.name, q.description, SUM(q.Duration)
FROM (
SELECT p.Name, et.description, Duration = 0
FROM person p
CROSS APPLY eventtype et
UNION ALL
SELECT p.Name, et.description, e.duration
FROM person p
INNER JOIN event e ON e.person_id = p.id
INNER JOIN eventtype et ON et.id = e.eventtypeid
) q
GROUP BY
q.Name, q.description
答案 1 :(得分:1)
您可以交叉加入person和eventtype,然后将结果加入事件表:
SELECT
p.Name,
et.Description,
COALESCE(e.duration,0)
FROM
person p
cross join
eventtype et
left join
event e
on
p.id = e.person_id and
et.id = e.eventtype_id
交叉连接是指对于左表中的每一行,它连接到右表中的每一行。
答案 2 :(得分:1)
如果您想为person
和eventtype
的每个组合添加一行,则会产生CROSS JOIN
。要获取我们需要加入event
的持续时间,但这需要是OUTER
加入,因为可能并不总是有一行。您对“总计”的使用表明,对于event
和person
的给定组合,可能会有多个event
,因此我们需要SUM
作为insert person values ( 1, 'Joe' )
insert person values ( 2, 'Bob' )
insert person values ( 3, 'Tim' )
insert eventtype values ( 1, 'Cake' )
insert eventtype values ( 2, 'Pie' )
insert eventtype values ( 3, 'Beer' )
insert event values ( 1, 1, 10 )
insert event values ( 1, 2, 10 )
insert event values ( 1, 2, 5 )
insert event values ( 2, 1, 10 )
insert event values ( 2, 2, 7 )
insert event values ( 3, 2, 8 )
insert event values ( 3, 3, 16 )
insert event values ( 1, 1, 10 )
好。
示例数据:
SELECT
PET.person_id
, PET.person_name
, PET.eventtype_id
, PET.eventtype_description
, ISNULL(SUM(E.duration), 0) total_duration
FROM
(
SELECT
P.id person_id
, P.name person_name
, ET.id eventtype_id
, ET.description eventtype_description
FROM
person P
CROSS JOIN eventtype ET
) PET
LEFT JOIN event E ON PET.person_id = E.person_id
AND PET.eventtype_id = E.eventtype_id
GROUP BY
PET.person_id
, PET.person_name
, PET.eventtype_id
, PET.eventtype_description
查询:
person_id person_name eventtype_id eventtype_description total_duration
----------- ----------- ------------ --------------------- --------------
1 Joe 1 Cake 20
1 Joe 2 Pie 15
1 Joe 3 Beer 0
2 Bob 1 Cake 10
2 Bob 2 Pie 7
2 Bob 3 Beer 0
3 Tim 1 Cake 0
3 Tim 2 Pie 8
3 Tim 3 Beer 16
Warning: Null value is eliminated by an aggregate or other SET operation.
(9 row(s) affected)
输出:
{{1}}