:
USE tempdb;
GO
CREATE TABLE dbo.tblPerson(PersonID INT, PersonName VARCHAR(255));
INSERT dbo.tblPerson SELECT 1, 'Bob'
UNION ALL SELECT 2, 'Charlie'
UNION ALL SELECT 3, 'Frank'
UNION ALL SELECT 4, 'Amore';
CREATE TABLE dbo.tblAddress(AddressID INT, PersonID INT, [Address] VARCHAR(255));
INSERT dbo.tblAddress SELECT 1,1,'255 1st Street'
UNION ALL SELECT 2,2,'99 Elm Street'
UNION ALL SELECT 3,2,'67 Poplar Street'
UNION ALL SELECT 4,2,'222 Oak Ave.'
UNION ALL SELECT 5,1,'36 Main Street, Suite 22'
UNION ALL SELECT 6,4,'77 Sicamore Ct.';
다음 쿼리는 원하는 결과를 얻을, 그것은 0, 1 또는 n 주소를 처리하는 방법을 보여줍니다. 이 경우 가장 높은 숫자는 3이지만 샘플 데이터를 약간 조정하여 원하는 경우 더 많은 주소로 재생할 수 있습니다. 당신이 그것을 실행하면
;WITH xMaster AS
(
SELECT PersonID, Address,
rn = ROW_NUMBER() OVER (PARTITION BY PersonID ORDER BY Address)
FROM dbo.tblAddress
)
SELECT PersonID, PersonName,[Address1],[Address2],[Address3] FROM
(
SELECT p.PersonID, p.PersonName,
[Address1] = x1.Address,
[Address2] = x2.Address,
[Address3] = x3.Address
FROM dbo.tblPerson AS p
LEFT OUTER JOIN xMaster AS x1 ON x1.PersonID = p.PersonID AND x1.rn = 1
LEFT OUTER JOIN xMaster AS x2 ON x2.PersonID = p.PersonID AND x2.rn = 2
LEFT OUTER JOIN xMaster AS x3 ON x3.PersonID = p.PersonID AND x3.rn = 3
) AS Addresses;
,이 표시됩니다 :
내가 얻을 수있는 쿼리를 알고 당신은 SQL을 인쇄 할 경우
DECLARE @col NVARCHAR(MAX) = N'',
@sel NVARCHAR(MAX) = N'',
@from NVARCHAR(MAX) = N'',
@query NVARCHAR(MAX) = N'';
;WITH m(c) AS
(
SELECT TOP 1 c = COUNT(*)
FROM dbo.tblAddress
GROUP BY PersonID
ORDER BY c DESC
)
SELECT @col = @col + ',[Address' + RTRIM(n.n) + ']',
@sel = @sel + ',' + CHAR(13) + CHAR(10) + '[Address' + RTRIM(n.n) + '] = x'
+ RTRIM(n.n) + '.Address',
@from = @from + CHAR(13) + CHAR(10) + ' LEFT OUTER JOIN xMaster AS x'
+ RTRIM(n.n) + ' ON x' + RTRIM(n.n) + '.PersonID = p.PersonID AND x'
+ RTRIM(n.n) + '.rn = ' + RTRIM(n.n)
FROM m CROSS JOIN (SELECT n = ROW_NUMBER() OVER (ORDER BY [object_id])
FROM sys.all_columns) AS n WHERE n.n <= m.c;
SET @query = N';WITH xMaster AS
(
SELECT PersonID, Address,
rn = ROW_NUMBER() OVER (PARTITION BY PersonID ORDER BY Address)
FROM dbo.tblAddress
)
SELECT PersonID, PersonName' + @col
+ ' FROM
(
SELECT p.PersonID, p.PersonName, ' + STUFF(@sel, 1, 1, '')
+ CHAR(13) + CHAR(10) + ' FROM dbo.tblPerson AS p ' + @from + '
) AS Addresses;';
PRINT @query;
--EXEC sp_executesql @query;
이 결과를 볼 수 있습니다 여기는 못생긴 엉망이지만, 당신의 요구 사항에 따라 달라집니다. 내 의견에서 제안한대로 쉼표로 구분 된 목록을 반환하거나 피벗 계층을 프레젠테이션 계층에서 다루는 것이 더 쉬울 것입니다.
Itzik Ben-Gan (SQL Server MVP)에는 동적 피벗의 표준 예가 있습니다. 인터넷 검색을 사용하면 많은 리소스를 찾을 수 있습니다. 또한, 여기 : http://stackoverflow.com/q/2922797/112196. 그럼에도 불구하고 이것을 달성하기 위해 동적 SQL을 생성하고 실행해야합니다. –
http://stackoverflow.com/questions/2209700/how-to-use-pivot-in-sql-server-2005-stored-procedure-joining-two-views 가능한 중복 –
동적 SQL로 이동해야합니다. 컴파일 할 때 모든 쿼리는 특정 모양 (즉, 특정 유형의 각 행이 준수 할 이름이 지정된 열 집합)을 사용하여 결과 집합을 반환해야합니다. –