SQL Server—将0、1或2行转换为具有2列的单行的SQL查询
我有一个模式如下SQL Server—将0、1或2行转换为具有2列的单行的SQL查询,sql,sql-server,tsql,Sql,Sql Server,Tsql,我有一个模式如下 Test -------------------- | Id | Name | -------------------- | 1 | A001 | | 2 | B001 | | 3 | C001 | -------------------- RelatedTest --------------------------------- | Id | Name | TestId | --------
Test
--------------------
| Id | Name |
--------------------
| 1 | A001 |
| 2 | B001 |
| 3 | C001 |
--------------------
RelatedTest
---------------------------------
| Id | Name | TestId |
---------------------------------
| 1 | Jack | NULL |
| 2 | Joe | 2 |
| 3 | Jane | 3 |
| 4 | Julia | 3 |
---------------------------------
为了简要说明此schema RelatedTest,需要测试一个可为空的FK,FKId可以出现0次、1次或2次,但不能超过2次
我正在执行一个t-SQL查询,该查询以以下格式报告Test
中的数据
TestReport
---------------------------------------------------------------------------
| TestId | TestName | RelatedTestName1 | RelatedTestName2 |
---------------------------------------------------------------------------
| 1 | A001 | NULL | NULL |
| 2 | B001 | Joe | NULL |
| 3 | C001 | Jane | Julia |
我可以安全地假设,TestReport
不需要为RelatedTestName设置超过两列
该模式超出了我的控制范围,我只是想查询它以获得一些报告
我一直在尝试使用Pivot
功能,但我不完全确定如何使用它,以便在没有RelatedTest
记录的情况下,RelatedTestName1
和RelatedTestName1
可以NULL
。另外,由于RelatedTestName
是一个varchar
,如果需要,我不确定如何应用适当的聚合。准备数据:
DROP TABLE IF EXISTS Test
GO
CREATE TABLE Test (Id INT PRIMARY KEY, Name VARCHAR(10)) ON [PRIMARY]
GO
INSERT INTO Test Values
(1, 'A001')
,(2, 'B001')
,(3, 'C001')
GO
DROP TABLE IF EXISTS RelatedTest
GO
CREATE TABLE RelatedTest (
Id INT,
Name VARCHAR(10),
TestId INT FOREIGN KEY REFERENCES Test (Id)
) ON [PRIMARY]
GO
INSERT INTO RelatedTest Values
(1, 'Jack', NULL)
,(2, 'Joe', 2)
,(3, 'Jane', 3)
,(3, 'Julia', 3)
GO
查询:
;WITH CTE AS
(
SELECT TestId = T.Id
,TestName = T.Name
,RelatedTestName = RT.Name
,RN = ROW_NUMBER() OVER(PARTITION BY T.Id ORDER BY RT.Id ASC)
FROM Test T
LEFT JOIN RelatedTest RT
ON T.Id = RT.TestId
)
SELECT DISTINCT
C.TestId
,C.TestName
,RelatedTestName1 = (SELECT RelatedTestName FROM CTE A WHERE A.TestId = C.TestId AND A.RN = 1)
,RelatedTestName2 = (SELECT RelatedTestName FROM CTE A WHERE A.TestId = C.TestId AND A.RN = 2)
FROM CTE C;