我有一张桌子,其中包含加入和离开组织的人员。
示例数据:Sql Fiddle
| pId | pName | Unit | YearIn | YearOut |
|-----|-----------|-------|--------|---------|
| 1 | Noah | North | 2013 | (null) |
| 2 | Liam | North | 2013 | 2014 |
| 3 | Mason | North | 2013 | 2014 |
| 4 | Jacob | North | 2000 | 2014 |
| 5 | William | West | 2000 | 2013 |
| 6 | Ethan | West | 2013 | 2013 |
| 7 | Michael | West | 2014 | 2015 |
| 8 | Alexander | West | 2013 | (null) |
多年> = 2013年,我希望获得按年份和单位分组的参赛作品和参赛作品数。
期望的输出(我不确定是否更容易或更难包含根本不存在数据的行):
| Year | Unit | NumIn | NumOut |
|------|-------|--------|--------|
| 2013 | North | 3 | (null) |
| 2013 | West | 2 | 2 |
| 2014 | North | (null) | 3 |
| 2014 | West | 1 | (null) |
| 2015 | North | (null) | (null) | (optional)
| 2015 | West | (null) | 1 |
为了让NumIn和NumOut成为一排,我猜需要某种自我加入 我试过:
SELECT p1.Year, p1.Unit, p1.NumIn, p2.NumOut FROM
(
SELECT YearIn AS Year, Unit, COUNT(pId) AS NumIn
FROM People
WHERE YearIn >= 2013
GROUP BY YearIn, Unit
) p1
LEFT JOIN
(
SELECT YearOut AS Year, Unit, COUNT(pId) AS NumOut
FROM People
WHERE YearOut >= 2013
GROUP BY YearOut, Unit
) p2
ON p1.Year = p2.Year AND p1.Unit = p2.Unit
但当然只能在左侧为我提供数据行。
| Year | Unit | NumIn | NumOut |
|------|-------|-------|--------|
| 2013 | North | 3 | (null) |
| 2013 | West | 2 | 2 |
| 2014 | West | 1 | (null) |
结果将输入到Excel中的数据透视表。所以我“欺骗”并使用简单的UNION查询来获取所有数据:
SELECT YearIn AS Year, Unit, COUNT(pId) AS NumIn, NULL AS NumOut
FROM People
WHERE YearIn >= 2013
GROUP BY YearIn, Unit
UNION ALL
SELECT YearOut AS Year, Unit, NULL AS NumIn, COUNT(pId) AS NumOut
FROM People
WHERE YearOut >= 2013
GROUP BY YearOut, Unit
ORDER BY Year, Unit;
结果:
| Year | Unit | NumIn | NumOut |
|------|-------|--------|--------|
| 2013 | North | 3 | (null) |
| 2013 | West | (null) | 2 |
| 2013 | West | 2 | (null) |
| 2014 | North | (null) | 3 |
| 2014 | West | 1 | (null) |
| 2015 | West | (null) | 1 |
这是数据透视表的基础,但我想知道如何在Sql Server中获得所需的结果。
我正在使用Sql Server 2008 R2,以防万一 谢谢!
答案 0 :(得分:3)
我认为你想要一个子查询和聚合:
SELECT Year, Unit, SUM(NumIn) as NumIn, SUM(NumOut) as NumOut
FROM (SELECT YearIn AS Year, Unit, COUNT(pId) AS NumIn, NULL AS NumOut
FROM People
WHERE YearIn >= 2013
GROUP BY YearIn, Unit
UNION ALL
SELECT YearOut AS Year, Unit, NULL AS NumIn, COUNT(pId) AS NumOut
FROM People
WHERE YearOut >= 2013
GROUP BY YearOut, Unit
) yu
GROUP BY Year, Unit;
答案 1 :(得分:2)
这应该有效:
WITH Years(y) AS
(
SELECT * FROM (VALUES('2013'),('2014'),('2015') ) AS tbl(y)
)
,Units AS
(
SELECT DISTINCT Unit FROM People
)
SELECT *
FROM Years CROSS JOIN Units
CROSS APPLY(SELECT (SELECT COUNT(*) FROM People AS inP WHERE inP.Unit=Units.Unit AND Years.y=inP.YearIn) AS NumIn
,(SELECT COUNT(*) FROM People AS outP WHERE outP.Unit=units.Unit AND Years.y=outP.YearOut ) As NumOut
) AS Counts
ORDER BY Years.y,Unit