组合按列分组的结果
Combine results of grouped-by columns
Consider table A:
Status Person
------ ------
Married Andy
Married Bob
Married Carol
Has Kids Bob
Has Kids Carol
Consider table B:
Married & Has Kids Bob
Married & Has Kids Carol
我可以得到table A,我可以得到table B,但是我如何同时显示A和B?我是 SQL 的新手,所以我对 UNION 的概念很模糊,那会是最好的方法吗?
编辑:
所以,我有点撒谎了。我不能准确地得到 table B,但类似:
Married Bob
Has Kids Bob
Married Carol
Has Kids Carol
我正在使用 SQL Server 2012。这是我对 table A 的查询:
SELECT Status,Person
FROM Records
WHERE Status IN ('Married', 'Has Kids')
GROUP BY Status,Person
ORDER BY Status,Person
查询 table B-ish:
SELECT Status,Person
FROM Records
WHERE Status='Married' AND Status='Has Kids'
GROUP BY Status,Person
ORDER BY Status,Person
我想要一个table这样的:
Status Person
------ ------
Married Andy
Married Bob
Married Carol
Has Kids Bob
Has Kids Carol
Married & Has Kids Bob
Married & Has Kids Carol
取决于"together"的意思。
如果你想查询到return 7行,即。 table A "concatenated" 的 5 行和 table B 的 2 行,然后 UNION
正是您所需要的。
或者,如果您希望查询 return 5 行 3 列,例如Person,A的Status,B的Status,那么一个JOIN
就是你所需要的。
首先,联盟。默认情况下,UNION
将消除重复记录。如果你想要重复记录 returned,或者如果你知道不能有重复记录,那么你应该使用 UNION ALL
:
SELECT Status, Person FROM A
UNION ALL
SELECT Status, Person FROM B
Status Person
------ ------
Married Andy
Married Bob
Married Carol
Has Kids Bob
Has Kids Carol
Married & Has Kids Bob
Married & Has Kids Carol
对于 JOIN,您可以选择 JOIN
、LEFT JOIN
、RIGHT JOIN
或 FULL JOIN
。第一个也称为 INNER JOIN
,其他 3 个称为外部连接,例如LEFT OUTER JOIN
。就个人而言,我从不使用多余的 INNER/OUTER 关键字。
联接有一个联接条件,在您的情况下是按人员联接 table A 和 B。内部联接将仅 return 记录人员同时存在于 A 和 B 中的位置,而外部联接将 return 来自 table (LEFT/RIGHT) 或两者的所有记录 tables(满)。所有可能的组合都将被 returned,例如如果 table A 和 table B 都有 3 条关于 X 的记录,那么查询将 return 编辑 9 行。
对于下面的示例,我假设 table B 也有 Dan
的记录,以说明差异。
内部联接:
SELECT A.Person, A.Status AS StatusA, B.Status AS StatusB
FROM A
JOIN B ON B.Person = A.Person
Person StatusA StatusB
------ ------- -------
Bob Married Married & Has Kids
Carol Married Married & Has Kids
Bob Has Kids Married & Has Kids
Carol Has Kids Married & Has Kids
左外连接:
SELECT A.Person, A.Status AS StatusA, B.Status AS StatusB
FROM A
LEFT JOIN B ON B.Person = A.Person
Person StatusA StatusB
------ ------- -------
Andy Married
Bob Married Married & Has Kids
Carol Married Married & Has Kids
Bob Has Kids Married & Has Kids
Carol Has Kids Married & Has Kids
右外连接:
SELECT B.Person, A.Status AS StatusA, B.Status AS StatusB
FROM A
RIGHT JOIN B ON B.Person = A.Person
Person StatusA StatusB
------ ------- -------
Bob Married Married & Has Kids
Carol Married Married & Has Kids
Bob Has Kids Married & Has Kids
Carol Has Kids Married & Has Kids
Dan Married & Has Kids
完全外部联接:
SELECT A.Person AS PersonA, A.Status AS StatusA
, B.Person AS PersonB, B.Status AS StatusB
FROM A
JOIN B ON B.Person = A.Person
PersonA StatusA PersonB StatusB
------- ------- ------- -------
Andy Married
Bob Married Bob Married & Has Kids
Carol Married Carol Married & Has Kids
Bob Has Kids Bob Married & Has Kids
Carol Has Kids Carol Married & Has Kids
Dan Married & Has Kids
注意:请记住,除非用 ORDER BY
子句明确指定,否则 SQL 不保证顺序,因此上面显示的行可能 return 以不同的顺序排列。
一种方法是使用自连接并将状态连接在一起:
select status, person from a
union all
select concat(married.status, ' & ', kids.status) status, kids.person
from a kids
join a married on kids.Person = married.Person
where kids.Status = 'Has Kids' and married.Status = 'Married'
这将为您提供示例中的准确输出。
或者您可以按照建议使用 for xml path
的相关子查询:
SELECT Status, Person FROM A
UNION ALL
SELECT Status = LTRIM(STUFF((
SELECT '& ' + a.Status
FROM a
WHERE a.Person = a1.Person
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, ''))
, person
FROM A A1 GROUP BY Person HAVING COUNT(Status) = 2
Consider table A:
Status Person
------ ------
Married Andy
Married Bob
Married Carol
Has Kids Bob
Has Kids Carol
Consider table B:
Married & Has Kids Bob
Married & Has Kids Carol
我可以得到table A,我可以得到table B,但是我如何同时显示A和B?我是 SQL 的新手,所以我对 UNION 的概念很模糊,那会是最好的方法吗?
编辑:
所以,我有点撒谎了。我不能准确地得到 table B,但类似:
Married Bob
Has Kids Bob
Married Carol
Has Kids Carol
我正在使用 SQL Server 2012。这是我对 table A 的查询:
SELECT Status,Person
FROM Records
WHERE Status IN ('Married', 'Has Kids')
GROUP BY Status,Person
ORDER BY Status,Person
查询 table B-ish:
SELECT Status,Person
FROM Records
WHERE Status='Married' AND Status='Has Kids'
GROUP BY Status,Person
ORDER BY Status,Person
我想要一个table这样的:
Status Person
------ ------
Married Andy
Married Bob
Married Carol
Has Kids Bob
Has Kids Carol
Married & Has Kids Bob
Married & Has Kids Carol
取决于"together"的意思。
如果你想查询到return 7行,即。 table A "concatenated" 的 5 行和 table B 的 2 行,然后 UNION
正是您所需要的。
或者,如果您希望查询 return 5 行 3 列,例如Person,A的Status,B的Status,那么一个JOIN
就是你所需要的。
首先,联盟。默认情况下,UNION
将消除重复记录。如果你想要重复记录 returned,或者如果你知道不能有重复记录,那么你应该使用 UNION ALL
:
SELECT Status, Person FROM A
UNION ALL
SELECT Status, Person FROM B
Status Person
------ ------
Married Andy
Married Bob
Married Carol
Has Kids Bob
Has Kids Carol
Married & Has Kids Bob
Married & Has Kids Carol
对于 JOIN,您可以选择 JOIN
、LEFT JOIN
、RIGHT JOIN
或 FULL JOIN
。第一个也称为 INNER JOIN
,其他 3 个称为外部连接,例如LEFT OUTER JOIN
。就个人而言,我从不使用多余的 INNER/OUTER 关键字。
联接有一个联接条件,在您的情况下是按人员联接 table A 和 B。内部联接将仅 return 记录人员同时存在于 A 和 B 中的位置,而外部联接将 return 来自 table (LEFT/RIGHT) 或两者的所有记录 tables(满)。所有可能的组合都将被 returned,例如如果 table A 和 table B 都有 3 条关于 X 的记录,那么查询将 return 编辑 9 行。
对于下面的示例,我假设 table B 也有 Dan
的记录,以说明差异。
内部联接:
SELECT A.Person, A.Status AS StatusA, B.Status AS StatusB
FROM A
JOIN B ON B.Person = A.Person
Person StatusA StatusB
------ ------- -------
Bob Married Married & Has Kids
Carol Married Married & Has Kids
Bob Has Kids Married & Has Kids
Carol Has Kids Married & Has Kids
左外连接:
SELECT A.Person, A.Status AS StatusA, B.Status AS StatusB
FROM A
LEFT JOIN B ON B.Person = A.Person
Person StatusA StatusB
------ ------- -------
Andy Married
Bob Married Married & Has Kids
Carol Married Married & Has Kids
Bob Has Kids Married & Has Kids
Carol Has Kids Married & Has Kids
右外连接:
SELECT B.Person, A.Status AS StatusA, B.Status AS StatusB
FROM A
RIGHT JOIN B ON B.Person = A.Person
Person StatusA StatusB
------ ------- -------
Bob Married Married & Has Kids
Carol Married Married & Has Kids
Bob Has Kids Married & Has Kids
Carol Has Kids Married & Has Kids
Dan Married & Has Kids
完全外部联接:
SELECT A.Person AS PersonA, A.Status AS StatusA
, B.Person AS PersonB, B.Status AS StatusB
FROM A
JOIN B ON B.Person = A.Person
PersonA StatusA PersonB StatusB
------- ------- ------- -------
Andy Married
Bob Married Bob Married & Has Kids
Carol Married Carol Married & Has Kids
Bob Has Kids Bob Married & Has Kids
Carol Has Kids Carol Married & Has Kids
Dan Married & Has Kids
注意:请记住,除非用 ORDER BY
子句明确指定,否则 SQL 不保证顺序,因此上面显示的行可能 return 以不同的顺序排列。
一种方法是使用自连接并将状态连接在一起:
select status, person from a
union all
select concat(married.status, ' & ', kids.status) status, kids.person
from a kids
join a married on kids.Person = married.Person
where kids.Status = 'Has Kids' and married.Status = 'Married'
这将为您提供示例中的准确输出。
或者您可以按照建议使用 for xml path
的相关子查询:
SELECT Status, Person FROM A
UNION ALL
SELECT Status = LTRIM(STUFF((
SELECT '& ' + a.Status
FROM a
WHERE a.Person = a1.Person
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, ''))
, person
FROM A A1 GROUP BY Person HAVING COUNT(Status) = 2