簡體   English   中英

SQL Pivot-動態列,無聚合

[英]SQL Pivot - Dynamic Columns, No Aggregation

我正在嘗試執行數據透視,但是我對數據透視的經驗不是很豐富,而且很棘手-我不知道如何構造查詢。

我有的:

  • 數據類型(記錄的測量類型)
  • 地點
  • 數據源(將在每個位置測量的事物)
  • 數據讀數(源度量)

附加信息:

  • 任何一個位置的光源數量都可以改變
  • 一個位置上的來源永遠不會超過5個
  • 每個來源/類型/日期僅保存1個讀數

在返回的表中:

  • 表格顯示了單個位置和日期的Data_Type信息和讀數
  • 列:Data_Name,Units,Is_Required(來自Data_Type表),以及每個Source的一列
  • 行:每個Data_Type一行
  • 行應按Type_Display_Order排序
  • 來源(額外的列)應按Source_Display_Order排序
  • 有些讀數是可選的,有些資料不是每天測量的-這些仍需要包含在表格中

例:

Table: Data_Type
Data_Type_ID  Data_Name  Units  Is_Required (BIT)  Type_Display_Order
-----------------------------------------------------------------------
1             Height     In.    1                  2
2             Length     In.    0                  3
3             Weight     Lbs.   1                  1

Table: Location
Location_ID  Location
-----------------------
1            West
2            East

Table: Data_Source
Data_Source_ID  Location_ID  Source_Name  Source_Display_Order
----------------------------------------------------------------
1               1            WCS          2
2               2            ECS          1
3               1            WBN          1

Table: Data_Reading
Data_Reading_ID  Data_Type_ID  Data_Source_ID  Reading  Reading_Date
----------------------------------------------------------------------
1                1             1               5        6/3/2016
2                3             2               3        5/1/2016
3                1             1               7        5/1/2016
4                2             3               2        6/3/2016
5                3             1               4        6/3/2016

查詢位置=“​​ West”,日期= 6/3/2016的所需結果:

Data_Type_ID  Data_Name  Units  Is_Required  WBN   WCS
---------------------------------------------------------
3             Weight     Lbs.   1            NULL  4
1             Height     In.    1            NULL  5
2             Length     In.    0            NULL  NULL

這個解決方案似乎是相似的: 樞軸動態列,沒有聚合,但是我仍然有一些問題。

這是我到目前為止的內容:

DECLARE @date DATE, @locationID INT

SET @date = CAST('6/3/2016' AS DATE)
SET @locationID = 1

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

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(s.Source_Name)
            FROM Data_Source s
            WHERE s.Location_ID = @locationID
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)')
        ,1,1,'')

SET @query = 'SELECT Data_Type_ID, Data_Name, Units, Is_Required, ' + @cols +
' FROM
(
    SELECT
          t.Data_Type_ID
        , t.Data_Name
        , t.Units
        , t.Is_Required
        , r.Reading
        , s.Source_Name
    FROM
        Data_Type t
    LEFT JOIN
        Data_Reading r ON t.Data_Type_ID = r.Data_Type_ID
    LEFT JOIN
        Data_Source s ON r.Data_Source_ID = s.Data_Source_ID
    WHERE
        r.Reading_Date = CAST(CAST(' + @date + ' AS NVARCHAR(10)) AS DATE)
        AND s.Location_ID = CAST(' + @locationID + ' AS INT)
) x
PIVOT
(
    MIN(Reading)
    for Source_Name in (' + @cols + ')
) p '

我的查詢現在可以正常工作,但是仍然有一些問題:

  • @cols未按Source_Display_Order排序
  • 行未按Type_Display_Order排序(我在X部分的內部SELECT語句中確實有ORDER BY,但我收到錯誤消息說那里沒有ORDER BY子句)
  • WHERE語句中的日期比較不起作用-出於某種原因,即使日期相同,也總是將其計算為False

解決了!

DECLARE @date DATE, @locationID INT

SET @date = CAST('6/3/2016' AS DATE)
SET @locationID = 1

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

SET @cols = STUFF((SELECT ',' + QUOTENAME(s.Source_Name)
            FROM Data_Source s
            WHERE s.Location_ID = @locationID
            ORDER BY s.Source_Display_Order
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)')
        ,1,1,'')

SET @query =
'SELECT
      Data_Type_ID
    , Data_Name
    , Units
    , Is_Required
    , ' + @cols + '
FROM
(
    SELECT
          t.Data_Type_ID
        , t.Data_Name
        , t.Units
        , t.Is_Required
        , r.Reading
        , s.Source_Name
        , t.Type_Display_Order
    FROM
        Data_Type t
    LEFT JOIN
        Data_Reading r ON t.Data_Type_ID = r.Data_Type_ID
    LEFT JOIN
        Data_Source s ON r.Data_Source_ID = s.Data_Source_ID
    WHERE
        r.Reading_Date = ''' + CAST(@date AS NVARCHAR(10)) + '''
        AND s.Location_ID = ' + CAST(@locationID AS NVARCHAR(20)) + '
) x
PIVOT
(
    MIN(Reading)
    for Source_Name in (' + @cols + ')
) p
ORDER BY
    Type_Display_Order'

EXECUTE(@query)

解決我的問題:

  • 將@date轉換為NVARCHAR,然后再添加到@query字符串中,並在@query內的引號中包含額外的引號以將新的NVARCHAR括起來
  • 從@cols中刪除DISTINCT子句並添加ORDER BY(我表中的所有名稱都是唯一的,因此DISTINCT是不必要的)
  • 將Type_Display_Order添加到內部SELECT語句中,並在PIVOT語句之后添加ORDER BY

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM