我一直在嘗試使用SQL Server樞軸一段時間,但我似乎並沒有得到正確的。我讀過一堆的答案,但不明白數據透視是如何工作的。我需要平鋪SQL Server行到列使用樞軸
我在寫存儲過程。我有表1(作爲TVP收到),並且需要使其看起來像表2(see this image for tables)。
重要說明:Table1.valueTypeID中的值不能硬編碼到邏輯中,因爲它們總是可以更改。因此,邏輯必須是超級動態的。
請參閱下面的代碼。數據透視表位於存儲過程的末尾。
-- Create date: 12/10/2013
-- Description: select all the contacts associated with received accountPassport
-- =============================================
ALTER PROCEDURE [dbo].[selectContactsPropsByAccountPassport]
-- Add the parameters for the stored procedure here
@accountPassport int,
@valueTypeFiltersTVP valueTypeFiltersTVP READONLY
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
DECLARE @accountID int;
DECLARE @contactsAppAccountPassport int;
DECLARE @searchResults TABLE
(
resultContactID int
);
DECLARE @resultContactID int;
DECLARE @contactsPropsForReturn TABLE
(
contactID int,
valueTypeID int,
value varchar(max)
);
create table #contactsPropsForReturnFiltered(contactID int,valueTypeID int, value varchar(max))
/*
DECLARE #contactsPropsForReturnFiltered TABLE
(
contactID int,
valueTypeID int,
value varchar(max)
);
*/
--2. get @contactsAppAccountPassport associated with recieved @accountPassport
-- go into dbo.accounts and get the @accountID associated with this @accountPassport
SELECT
@accountID = ID
FROM
dbo.accounts
WHERE
passport = @accountPassport
-- go into dbo.accountsProps and get the value (@contactsAppAccountPassport) where valueType=42 and accountID = @accountID
SELECT
@contactsAppAccountPassport = value
FROM
dbo.accountsProps
WHERE
(valueTypeID=42) AND (accountID = @accountID)
--3. get all the contact ID's from dbo.contacts associated with @contactsAppAccountPassport
INSERT INTO
@searchResults
SELECT
ID
FROM
dbo.contacts
WHERE
contactsAppAccountPassport = @contactsAppAccountPassport
--4. Get the props of all contact ID's from 3.
--start for each loop....our looping object is @resultContactID row. if there are more rows, we keep looping.
DECLARE searchCursor CURSOR FOR
SELECT
resultContactID
FROM
@searchResults
OPEN searchCursor
FETCH NEXT FROM searchCursor INTO @resultContactID
WHILE (@@FETCH_STATUS=0)
BEGIN
INSERT INTO
@contactsPropsForReturn
SELECT
contactID,
valueTypeID,
value
FROM
dbo.contactsProps
WHERE
contactID = @resultContactID
FETCH NEXT FROM searchCursor INTO @resultContactID
END --end of WHILE loop
--end of cursor (both CLOSE and DEALLOCATE necessary)
CLOSE searchCursor
DEALLOCATE searchCursor
-- select and return only the props that match with the requested props
-- (we don't want to return all the props, only the ones requested)
INSERT INTO
#contactsPropsForReturnFiltered
SELECT
p.contactID,
p.valueTypeID,
p.value
FROM
@contactsPropsForReturn as p
INNER JOIN
@valueTypeFiltersTVP as f
ON
p.valueTypeID = f.valueTypeID
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX);
SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(ValueTypeId)
FROM #contactsPropsForReturnFiltered
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'');
set @query = 'SELECT contactid, ' + @cols + ' from
(
select contactid
, Value
,ValueTypeId
from #contactsPropsForReturnFiltered
) x
pivot
(
min(Value)
for ValueTypeId in (' + @cols + ')
) p ';
execute(@query);
END
你嘗試過什麼? –
@GordonLinoff我用遊標動態地構建了新表,但是在工作中的每個人都說遊標很貴,應該避免。對此有何看法? – quelquecosa
遊標通常很貴,應該避免,特別是當查詢可以完成這項工作時。在MS SQL文檔中查找'pivot'來看看它是如何工作的。 –