2013-02-16 44 views
2

的情況: 3源表:如何在一行中將多行中的特定字段「合併」爲多個不同的字段?

1.用戶(包含唯一ID和用戶特定的屬性,如firstNamegivenNameStreetAddress等)

2. MigrationFeatures(包含唯一ID和Feature_Name

3. Link_Users_and_Features(包含唯一ID期從UsersFeatures以及一個Status柱(INT))

在鏈接表中,對每個用戶有因爲有在Feature表中的行一樣多的行和每行中(每個用戶)鏈接到一個Feature。每個鏈接行還包含一個狀態值列,該列可以具有不同的值 - 根據特定用戶的特定Feature的遷移狀態。

目標

有一個完全動態查詢/ SP,返回一個行,並與每個Feature的用於該特定用戶的遷移狀態的每個用戶 - 各遷移狀態欄shold根據Feature_Name被命名來自Features表中相應的Feature。當我在Feature表中添加Feature時,不必手動修改所需的查詢代碼。

提示:Feature表早已INSERT觸發器其爲每個用戶創建這個附加列並沒有對有關列的完整性,因此所有用戶將永遠在鏈接表中的所有相應的行所有Features

爲什麼我想有:

到現在爲止,我有一個包含所有用戶特定的列(Name, givenName, StreetAddress,等)以及所有的遷移功能狀態欄(SIDhist migrated, homefolder migrated,等),一個單一的表,爲所有用戶保存所有遷移狀態數據。

不幸的是,這是完全靜態的,每當我增加了新的Feature,我要修改這個主表。未來,技能較低的人將使用底層系統,他們不會進入DB代碼或模式,而只會將記錄添加到Featureuser表中。

這裏的代碼來創建用戶DB:

CREATE TABLE [dbo].[Users](
     [Users_ID] [int] IDENTITY(1,1) NOT NULL, 
     [FMOUser_givenName] [nvarchar](max) NULL, 
     [FMOUser_sn] [nvarchar](max) NULL, 
     [FMOUser_streetAddress] [nvarchar](max) NULL, 
     [ExcludeFromMigration] [bit] NULL, 
    CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED 
    (
     [Users_ID] ASC 
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
    ) ON [PRIMARY] 

    GO 

這裏的代碼來創建功能表:

CREATE TABLE [dbo].[Features](
    [Features_ID] [int] IDENTITY(1,1) NOT NULL, 
    [Feature_Name] [nvarchar](max) NOT NULL 
CONSTRAINT [PK_Features] PRIMARY KEY CLUSTERED 
(
    [Features_ID] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 

代碼來創建鏈接表:

CREATE TABLE [dbo].[link_Users__with__Features](
    [link_Users__with__Features_ID] [int] IDENTITY(1,1) NOT NULL, 
    [FMO_Users_ID] [int] NOT NULL, 
    [Features_Migration_Core_ID] [int] NOT NULL, 
    [StatusValue] [int] NOT NULL, 
    [Description] [nvarchar](max) NULL, 
CONSTRAINT [PK_link_Users__with__Features] PRIMARY KEY CLUSTERED 
(
    [link_Users__with__Features_ID] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

我已經研究了什麼?

我發現下面的例子:

http://www.dbforums.com/microsoft-sql-server/1673127-view-multiple-records-single-row.html

這不把單個列從下新的列名多行的一個單列,但它不是動態的 - 意思是:它不拔出從Features表中的相應「特徵」行中的目標列名稱也不能處理動態數字Features

因爲我對T-SQL比較陌生,所以我失去了如何解決這個問題。

由於這是我在堆棧溢出時的第一個問題,請原諒我,如果我錯過了手續。請糾正我,我會做得更好:-)

提示:我已經查找了提出的「重複」到我的問題,但似乎沒有哪個甚至略有匹配我的問題。

+1

從外觀上來看,'SQL服務器動態pivot'應該是關鍵字搜索Web或專本網站。 – 2013-02-16 23:19:11

+0

謝謝,這讓我走向了正確的方向。 – 2013-02-17 11:15:08

回答

0

下面的代碼做什麼,我在我最初的問題要求:(請注意,我已經介紹了一個額外的觀點:view_Users_ _StatusValues結合用戶,鏈路表和特徵)

它是靈感來自:http://www.mssqltips.com/sqlservertip/2783/script-to-create-dynamic-pivot-queries-in-sql-server/

代碼:

use [your_database] 

-- *** Get the column names for the target 'table' out from the features table 
DECLARE @columns NVARCHAR(MAX), @sql NVARCHAR(MAX); 
SET @columns = N''; 
SELECT @columns += N',' + QUOTENAME(Feature_Name) 
    FROM (SELECT p.Feature_Name FROM dbo.Features AS p 
    INNER JOIN dbo.link_Users__with__Features AS o 
    ON p.Features_ID = o.Features_ID 
    GROUP BY p.Feature_Name) AS x; 

-- *** remove unneccessary, leading ',' *** 
set @columns = STUFF(REPLACE(@columns, ', p.[', ',['), 1, 1, '') 
-- print @columns 

-- *** Create the SQL code which will produce the correct output table *** 
SET @sql = N' 
select * from dbo.view_FMO_Users__and__StatusValues 
pivot(
     max(StatusValue) -- use any aggregate function (needed for pivoting) 
     for Feature_Name in (' + @columns + ')) as FeatureStatusValue' 

-- PRINT @sql; 
EXEC sp_executesql @sql; 
相關問題