MS SQL 旋转另一个 Table 多次
MS SQL Pivot Another Table Multiple Times
我有一个具有以下结构的数据库
ID Name
1 John
2 Doe
3 Dave
4 Smith
另一个table持有员工亲属
ID EmpID RelativeType Name
1 1 Son x
2 1 Daughter y
3 1 Wife a
4 1 Friend b
5 1 Father c
6 1 Friend e
孩子最多可以固定8个,朋友最多可以固定3个
我能够在下面进行数据透视查询以带孩子,但无法再次进行数据透视以获取 3 个朋友、父亲等。
这是我的查询:
select *
from
(
select e.ID, e.FirstName,
CASE WHEN es.RelativeType = 'Son' or es.RelativeType = 'Daughter' THEN es.FirstName END as Child, CASE WHEN es.RelativeType = 'Son' or es.RelativeType = 'Daughter' THEN CONCAT('Child ',ROW_NUMBER() OVER (ORDER BY e.ID)) END as Relation
from Employee e
left join EmployeeRelatives es
on e.ID = es.EmpID
group by
e.ID, e.FirstName,es.RelativeID,es.FirstName
) x
pivot
(
max(Child)
for Relation in([Child 1],[Child 2],[Child 3], [Child 4], [Child 5], [Child 6], [Child 7], [Child 8])
) as p1
以上查询returns结果如下。
EmpID , Name, Child 1, Child 2,Child 3, Child 4, Child 5, Child 6
1 John x y NULL NULL NULL NULL
当我制作多个支点时,它 returns 多行,这不是必需的。
我需要修改上面的查询以带来想要的结果
需要的结果集如下
EmpID , Name, Child 1, Child 2, Child 3, Child 4, Wife, Friend 1, Friend 2, Friend 3, Father
1 John x y NULL NULL a b e NULL c
我正在使用 MS SQL 2014.
我在这里使用了所谓的 "CROSS PIVOT"。
就像我说的,这不太好;你真的应该在你的表现层这样做。该解决方案不可扩展,而且维护起来可能很痛苦。无论如何,这里是:
CREATE TABLE #Employee (ID int, [Name] varchar(10));
INSERT INTO #Employee
VALUES(1,'John'),
(2,'Doe'),
(3,'Dave'),
(4,'Smith');
CREATE TABLE #Relative (ID int, EmpID int, RelativeType varchar(10), [Name] char(1));
INSERT INTO #Relative
VALUES(1,1,'Son','x'),
(2,1,'Daughter','y'),
(3,1,'Wife','a'),
(4,1,'Friend','b'),
(5,1,'Father','c'),
(6,1,'Friend','e');
WITH RNs AS (
SELECT *,
CASE RelativeType WHEN 'Son' THEN 'Child'
WHEN 'Daughter' THEN 'Child'
WHEN 'Mother' THEN 'Parent'
WHEN 'Father' THEN 'Parent'
WHEN 'Wife' THEN 'Spouse'
WHEN 'Husband' THEN 'Spouse'
ELSE RelativeType END AS Relation,
ROW_NUMBER() OVER (PARTITION BY EmpID,
CASE RelativeType WHEN 'Son' THEN 'Child'
WHEN 'Daughter' THEN 'Child'
WHEN 'Mother' THEN 'Parent'
WHEN 'Father' THEN 'Parent'
WHEN 'Wife' THEN 'Spouse'
WHEN 'Husband' THEN 'Spouse'
ELSE RelativeType END
ORDER BY ID ASC) RN
FROM #Relative R)
SELECT E.ID AS EmpID,
E.[Name],
MAX(CASE WHEN R.Relation = 'Child' AND RN = 1 THEN R.[Name] END) AS Child1,
MAX(CASE WHEN R.Relation = 'Child' AND RN = 2 THEN R.[Name] END) AS Child2,
MAX(CASE WHEN R.Relation = 'Child' AND RN = 3 THEN R.[Name] END) AS Child3,
MAX(CASE WHEN R.Relation = 'Child' AND RN = 4 THEN R.[Name] END) AS Child4,
MAX(CASE WHEN R.Relation = 'Child' AND RN = 5 THEN R.[Name] END) AS Child5,
MAX(CASE WHEN R.Relation = 'Child' AND RN = 6 THEN R.[Name] END) AS Child6,
MAX(CASE WHEN R.Relation = 'Child' AND RN = 7 THEN R.[Name] END) AS Child7,
MAX(CASE WHEN R.Relation = 'Child' AND RN = 8 THEN R.[Name] END) AS Child8,
MAX(CASE WHEN R.Relation = 'Spouse' AND RN = 1 THEN R.[Name] END) AS Spouse,
MAX(CASE WHEN R.Relation = 'Friend' AND RN = 1 THEN R.[Name] END) AS Friend1,
MAX(CASE WHEN R.Relation = 'Friend' AND RN = 2 THEN R.[Name] END) AS Friend2,
MAX(CASE WHEN R.Relation = 'Friend' AND RN = 3 THEN R.[Name] END) AS Friend3
--You get the idea
FROM #Employee E
JOIN RNs R ON E.ID = R.EmpID
GROUP BY E.ID,
E.[Name];
GO
DROP TABLE #Employee;
DROP TABLE #Relative;
你可以试试看,希望对你有帮助:)
祝你好运!! :)
WITH Children AS
(
SELECT e.EmpID, e.FirstName EmpName, er.FirstName RelName,
'Child' + CONVERT(NVARCHAR(2), ROW_NUMBER() OVER (PARTITION BY er.EmpID ORDER BY er.RelativeID)) AS 'Relation'
FROM Employee e
LEFT JOIN EmployeeRelatives er ON e.EmpID = er.EmpID
WHERE er.RelativeType IN ('Son', 'Daughter')
),
ChildInRow AS
(
SELECT *
FROM Children
PIVOT
(
MAX(RelName)
FOR Relation in([Child1],[Child2],[Child3], [Child4], [Child5], [Child6], [Child7], [Child8])
) AS p1
),
Friends AS
(
SELECT e.EmpID, e.FirstName EmpName, er.FirstName RelName,
'Friend' + CONVERT(NVARCHAR(2), ROW_NUMBER() OVER (PARTITION BY er.EmpID ORDER BY er.RelativeID)) AS 'Relation'
FROM Employee e
LEFT JOIN EmployeeRelatives er ON e.EmpID = er.EmpID
WHERE er.RelativeType = 'Friend'
),
FriendsInRow AS
(
SELECT *
FROM Friends
PIVOT
(
MAX(RelName)
FOR Relation in([Friend1],[Friend2],[Friend3])
) AS p1
),
AllWife AS
(
SELECT e.EmpID, e.FirstName EmpName, er.FirstName RelName, 'Wife' AS 'Relation',
ROW_NUMBER() OVER (PARTITION BY er.EmpID ORDER BY er.RelativeID) wife_row_num
FROM Employee e
LEFT JOIN EmployeeRelatives er ON e.EmpID = er.EmpID
WHERE er.RelativeType = 'Wife'
),
WifeInRow AS
(
SELECT * FROM AllWife WHERE wife_row_num = 1
),
AllFather AS
(
SELECT e.EmpID, e.FirstName EmpName, er.FirstName RelName, 'Father' AS 'Relation',
ROW_NUMBER() OVER (PARTITION BY er.EmpID ORDER BY er.RelativeID) father_row_num
FROM Employee e
LEFT JOIN EmployeeRelatives er ON e.EmpID = er.EmpID
WHERE er.RelativeType = 'Father'
),
FatherInRow AS
(
SELECT * FROM AllFather WHERE father_row_num = 1
)
SELECT e.EmpID, e.FirstName,
ISNULL(Child1, '') Child1, ISNULL(Child2, '') Child2, ISNULL(Child3, '') Child3, ISNULL(Child4, '') Child4, ISNULL(Child5, '') Child5, ISNULL(Child6, '') Child6, ISNULL(Child7, '') Child7, ISNULL(Child8, '') Child8,
ISNULL(w.RelName, '') Wife,
ISNULL(Friend1, '') Friend1, ISNULL(Friend2, '') Friend2, ISNULL(Friend3, '') Friend3,
ISNULL(fa.RelName, '') Father
FROM Employee e
FULL OUTER JOIN ChildInRow c ON e.EmpID = c.EmpID
FULL OUTER JOIN FriendsInRow f ON e.EmpID = f.EmpID
FULL OUTER JOIN WifeInRow w ON e.EmpID = w.EmpID
FULL OUTER JOIN FatherInRow fa ON e.EmpID = fa.EmpID
结果应该是这样的:
我有一个具有以下结构的数据库
ID Name
1 John
2 Doe
3 Dave
4 Smith
另一个table持有员工亲属
ID EmpID RelativeType Name
1 1 Son x
2 1 Daughter y
3 1 Wife a
4 1 Friend b
5 1 Father c
6 1 Friend e
孩子最多可以固定8个,朋友最多可以固定3个
我能够在下面进行数据透视查询以带孩子,但无法再次进行数据透视以获取 3 个朋友、父亲等。
这是我的查询:
select *
from
(
select e.ID, e.FirstName,
CASE WHEN es.RelativeType = 'Son' or es.RelativeType = 'Daughter' THEN es.FirstName END as Child, CASE WHEN es.RelativeType = 'Son' or es.RelativeType = 'Daughter' THEN CONCAT('Child ',ROW_NUMBER() OVER (ORDER BY e.ID)) END as Relation
from Employee e
left join EmployeeRelatives es
on e.ID = es.EmpID
group by
e.ID, e.FirstName,es.RelativeID,es.FirstName
) x
pivot
(
max(Child)
for Relation in([Child 1],[Child 2],[Child 3], [Child 4], [Child 5], [Child 6], [Child 7], [Child 8])
) as p1
以上查询returns结果如下。
EmpID , Name, Child 1, Child 2,Child 3, Child 4, Child 5, Child 6
1 John x y NULL NULL NULL NULL
当我制作多个支点时,它 returns 多行,这不是必需的。 我需要修改上面的查询以带来想要的结果
需要的结果集如下
EmpID , Name, Child 1, Child 2, Child 3, Child 4, Wife, Friend 1, Friend 2, Friend 3, Father
1 John x y NULL NULL a b e NULL c
我正在使用 MS SQL 2014.
我在这里使用了所谓的 "CROSS PIVOT"。
就像我说的,这不太好;你真的应该在你的表现层这样做。该解决方案不可扩展,而且维护起来可能很痛苦。无论如何,这里是:
CREATE TABLE #Employee (ID int, [Name] varchar(10));
INSERT INTO #Employee
VALUES(1,'John'),
(2,'Doe'),
(3,'Dave'),
(4,'Smith');
CREATE TABLE #Relative (ID int, EmpID int, RelativeType varchar(10), [Name] char(1));
INSERT INTO #Relative
VALUES(1,1,'Son','x'),
(2,1,'Daughter','y'),
(3,1,'Wife','a'),
(4,1,'Friend','b'),
(5,1,'Father','c'),
(6,1,'Friend','e');
WITH RNs AS (
SELECT *,
CASE RelativeType WHEN 'Son' THEN 'Child'
WHEN 'Daughter' THEN 'Child'
WHEN 'Mother' THEN 'Parent'
WHEN 'Father' THEN 'Parent'
WHEN 'Wife' THEN 'Spouse'
WHEN 'Husband' THEN 'Spouse'
ELSE RelativeType END AS Relation,
ROW_NUMBER() OVER (PARTITION BY EmpID,
CASE RelativeType WHEN 'Son' THEN 'Child'
WHEN 'Daughter' THEN 'Child'
WHEN 'Mother' THEN 'Parent'
WHEN 'Father' THEN 'Parent'
WHEN 'Wife' THEN 'Spouse'
WHEN 'Husband' THEN 'Spouse'
ELSE RelativeType END
ORDER BY ID ASC) RN
FROM #Relative R)
SELECT E.ID AS EmpID,
E.[Name],
MAX(CASE WHEN R.Relation = 'Child' AND RN = 1 THEN R.[Name] END) AS Child1,
MAX(CASE WHEN R.Relation = 'Child' AND RN = 2 THEN R.[Name] END) AS Child2,
MAX(CASE WHEN R.Relation = 'Child' AND RN = 3 THEN R.[Name] END) AS Child3,
MAX(CASE WHEN R.Relation = 'Child' AND RN = 4 THEN R.[Name] END) AS Child4,
MAX(CASE WHEN R.Relation = 'Child' AND RN = 5 THEN R.[Name] END) AS Child5,
MAX(CASE WHEN R.Relation = 'Child' AND RN = 6 THEN R.[Name] END) AS Child6,
MAX(CASE WHEN R.Relation = 'Child' AND RN = 7 THEN R.[Name] END) AS Child7,
MAX(CASE WHEN R.Relation = 'Child' AND RN = 8 THEN R.[Name] END) AS Child8,
MAX(CASE WHEN R.Relation = 'Spouse' AND RN = 1 THEN R.[Name] END) AS Spouse,
MAX(CASE WHEN R.Relation = 'Friend' AND RN = 1 THEN R.[Name] END) AS Friend1,
MAX(CASE WHEN R.Relation = 'Friend' AND RN = 2 THEN R.[Name] END) AS Friend2,
MAX(CASE WHEN R.Relation = 'Friend' AND RN = 3 THEN R.[Name] END) AS Friend3
--You get the idea
FROM #Employee E
JOIN RNs R ON E.ID = R.EmpID
GROUP BY E.ID,
E.[Name];
GO
DROP TABLE #Employee;
DROP TABLE #Relative;
你可以试试看,希望对你有帮助:) 祝你好运!! :)
WITH Children AS
(
SELECT e.EmpID, e.FirstName EmpName, er.FirstName RelName,
'Child' + CONVERT(NVARCHAR(2), ROW_NUMBER() OVER (PARTITION BY er.EmpID ORDER BY er.RelativeID)) AS 'Relation'
FROM Employee e
LEFT JOIN EmployeeRelatives er ON e.EmpID = er.EmpID
WHERE er.RelativeType IN ('Son', 'Daughter')
),
ChildInRow AS
(
SELECT *
FROM Children
PIVOT
(
MAX(RelName)
FOR Relation in([Child1],[Child2],[Child3], [Child4], [Child5], [Child6], [Child7], [Child8])
) AS p1
),
Friends AS
(
SELECT e.EmpID, e.FirstName EmpName, er.FirstName RelName,
'Friend' + CONVERT(NVARCHAR(2), ROW_NUMBER() OVER (PARTITION BY er.EmpID ORDER BY er.RelativeID)) AS 'Relation'
FROM Employee e
LEFT JOIN EmployeeRelatives er ON e.EmpID = er.EmpID
WHERE er.RelativeType = 'Friend'
),
FriendsInRow AS
(
SELECT *
FROM Friends
PIVOT
(
MAX(RelName)
FOR Relation in([Friend1],[Friend2],[Friend3])
) AS p1
),
AllWife AS
(
SELECT e.EmpID, e.FirstName EmpName, er.FirstName RelName, 'Wife' AS 'Relation',
ROW_NUMBER() OVER (PARTITION BY er.EmpID ORDER BY er.RelativeID) wife_row_num
FROM Employee e
LEFT JOIN EmployeeRelatives er ON e.EmpID = er.EmpID
WHERE er.RelativeType = 'Wife'
),
WifeInRow AS
(
SELECT * FROM AllWife WHERE wife_row_num = 1
),
AllFather AS
(
SELECT e.EmpID, e.FirstName EmpName, er.FirstName RelName, 'Father' AS 'Relation',
ROW_NUMBER() OVER (PARTITION BY er.EmpID ORDER BY er.RelativeID) father_row_num
FROM Employee e
LEFT JOIN EmployeeRelatives er ON e.EmpID = er.EmpID
WHERE er.RelativeType = 'Father'
),
FatherInRow AS
(
SELECT * FROM AllFather WHERE father_row_num = 1
)
SELECT e.EmpID, e.FirstName,
ISNULL(Child1, '') Child1, ISNULL(Child2, '') Child2, ISNULL(Child3, '') Child3, ISNULL(Child4, '') Child4, ISNULL(Child5, '') Child5, ISNULL(Child6, '') Child6, ISNULL(Child7, '') Child7, ISNULL(Child8, '') Child8,
ISNULL(w.RelName, '') Wife,
ISNULL(Friend1, '') Friend1, ISNULL(Friend2, '') Friend2, ISNULL(Friend3, '') Friend3,
ISNULL(fa.RelName, '') Father
FROM Employee e
FULL OUTER JOIN ChildInRow c ON e.EmpID = c.EmpID
FULL OUTER JOIN FriendsInRow f ON e.EmpID = f.EmpID
FULL OUTER JOIN WifeInRow w ON e.EmpID = w.EmpID
FULL OUTER JOIN FatherInRow fa ON e.EmpID = fa.EmpID
结果应该是这样的: