2016-10-10 16 views
0

我試圖得到一個表,看起來像:SQL Query(T-SQL)根據所有可用的分類狀態對特定Name的事務狀態進行計數?

Columns : [District] [Name] [Status1] [Status2] [Status3] 

Data: DistrictA MrChan 1  1  1 

Data: DistrictB MrFoo 1  0  2 

Data: DistrictB MsLucy 0  1  0 
(sorry the table turns out unexpected after posting) 

select StatusID, StatusCode from 
BookingStatus retrieves all categorical statuses Status1, Status2, Status3 


select userid, DistrictA, StatusID from 
UnitBooking retrieve multiple rows which represent booking transactions. 

在上面的例子露西女士做了1個預訂,她將有1行中UnitBooking。富先生有三排,陳先生也有三排。

實施例的數據:

select [userid], [username], [District], [StatusID] from UnitBooking 

[1],[MrChan],[DistrictA],[1] 

[1],[MrChan],[DistrictA],[2] 

[1],[MrChan],[DistrictA],[3] 

[2],[MrFoo],[DistrictB],[1] 

[2],[MrFoo],[DistrictB],[3] 

[2],[MrFoo],[DistrictB],[3] 

[3],[MsLucy],[DistrictB],[2] 


select [StatusID], [StatusCode] from BookingStatus 

[1],[Status1] 

[2],[Status2] 

[3],[Status3] 

什麼是T-SQL生成結果集?

非常感謝

+0

請發表一些樣品數據爲這兩個表 – TheGameiswar

+0

你想創建一個這樣的表?或者你有桌子,你想從他們這裏提取數據? – GuidoG

+0

我已經有了將數據放入表格的表格和機制。我試圖編寫一個SQL來報告 –

回答

0
select 
district, 
username, 
sum(case when bs.statusid=1 then 1 else 0 end) 'status1', 
sum(case when bs.statusid=2 then 1 else 0 end) 'status2', 
sum(case when bs.statusid=3 then 1 else 0 end) 'status13' 
from 
unitbooking ub 
join 
BookingStatus Bs 
on bs.statusid=ub.statusid 
group by district,username 
+0

這是智能使用'case when'!謝謝 –

+0

假設未來有人在BookingStatus表中添加了第四個狀態行,即'Status4'。什麼是SQL動態地反映這種新的狀態,而不修改這個SQL? –

+0

看到這個:http://dba.stackexchange。COM /問題/ 48393 /假冒列名的動態可到了unpivot – TheGameiswar

0

我想出了,對於我的報告工作的SQL,但我不擅長什麼STUFF函數和XML PATH部分做的,除了它的工作原理。這裏所說:

DECLARE @cols AS NVARCHAR(MAX),@query AS NVARCHAR(MAX) 

SELECT @cols = STUFF(( SELECT ', SUM(CASE WHEN ub.BookingStatus=' 
        + Cast(ItemID as nvarchar(128)) 
        + ' THEN 1 ELSE 0 END) ' 
        + QUOTENAME(StatusCode) 
        FROM customtable_BookingStatus 
        --WHERE ItemID Not In (1) 
        GROUP BY StatusCode 
          ,ItemID 
        ORDER BY ItemID 
        FOR XML PATH('') 
        ,TYPE 
        ).value('.', 'NVARCHAR(MAX)'), 1, 1, '') 

SET @query = 'SELECT usr.FullName, usi.District, ' 
     +'cnt.[OPEN] as [DUALLANGUAGE], cnt.BOOKED, cnt.CONFIRMED, cnt.SOLD from customtable__User usr 
      left join customtable_Public_User_Info usi on usi.UserID = usr.UserID 
      inner join ' 
     +'(SELECT ub.UserID,' + @cols 
     +'from customtable_UnitBooking ub 
      join customtable_BookingStatus bs on bs.ItemID = ub.BookingStatus 
      group by ub.UserId, ub.BookingStatus) ' 
     +'cnt on cnt.UserID = usr.UserID' 
--Print @query 
EXEC sp_executesql @query; 

下面是一些增值的便利:在BookingStatus表

- 支持新的項目動態。仍然需要在最終的@query中顯式聲明新列的名稱。

從技術上講,新列的名稱也可以在@query中動態添加一個額外的STUFF函數,它具有類似的簽名,用於檢索純逗號分隔的列。這裏的片段:

DECLARE @colsForQuery AS NVARCHAR(MAX) 
SELECT @colsForQuery = STUFF(( SELECT ',cnt.' + QUOTENAME(StatusCode) 
        FROM customtable_BookingStatus 
        --WHERE ItemID Not In (1) 
        GROUP BY StatusCode 
          ,ItemID 
        ORDER BY ItemID 
        FOR XML PATH('') 
        ,TYPE 
        ).value('.', 'NVARCHAR(MAX)'), 1, 1, '') 

產生這樣的:

cnt.[OPEN],cnt.[BOOKED],cnt.[SOLD],cnt.[CONFIRMED] 

- 我的報告有雙重語言,但如果所有列是完全動態的

使用-Omit列不容易「WHERE項目ID不在( 1)「或刪除@query

-Watch out與T-SQL關鍵字衝突的列,例如,我必須將[OPEN]包裝爲其關鍵字

總的來說我覺得TheGameiswar是正確答案。我只是根據內部評論中提供的URL來擴展他的解決方案。

相關問題