為什麼我的 PIVOT 查詢使用不包含 NULL 的數據集生成 NULL 結果?

馬特

我有一個設備數據庫,其中包含有關設備的數據,包括名稱、位置以及一些數字和字符串屬性。我正在嘗試執行查詢,僅將具有數值的那些屬性拉入數據透視表。

當我平淡地查詢數據時,數據看起來不錯。但是當我PIVOT在同一個數據集上運行查詢時,所有結果都是NULL.

設置:

/* database setup and data insert */

USE [master] ;
GO

IF EXISTS ( SELECT * FROM sys.databases WHERE [name] = N'DeviceDatabase' )
BEGIN
    ALTER DATABASE [DeviceDatabase] SET SINGLE_USER WITH ROLLBACK IMMEDIATE ;
    DROP DATABASE [DeviceDatabase] ;
END
CREATE DATABASE [DeviceDatabase] ;
GO

USE [DeviceDatabase] ;
GO

CREATE TABLE dbo.Devices
(
    [id]                        INT             NOT NULL    IDENTITY (1,1)
        CONSTRAINT      [PK_Devices]            PRIMARY KEY CLUSTERED
    , [device_name]             VARCHAR(50)     NOT NULL
    , [device_display_name]     VARCHAR(50)     NOT NULL
    , [device_location]         VARCHAR(50)     NULL
) ;

CREATE TABLE dbo.DeviceGroups
(
    [id]                        INT             NOT NULL    IDENTITY (1,1)
        CONSTRAINT      [PK_DeviceGroups]       PRIMARY KEY CLUSTERED
    , [device_group_name]       VARCHAR(50)     NOT NULL
) ;

CREATE TABLE dbo.DeviceDeviceGroups
(
    [id]                        INT             NOT NULL    IDENTITY (1,1)
        CONSTRAINT      [PK_DeviceDeviceGroups] PRIMARY KEY CLUSTERED
    , [device_id]               INT             NOT NULL
        CONSTRAINT      [FK_DeviceDeviceGroups_Devices]
        FOREIGN KEY REFERENCES dbo.Devices ( [id] )
    , [group_id]                INT             NOT NULL
        CONSTRAINT      [FK_DeviceDeviceGroups_DeviceGroups]
        FOREIGN KEY REFERENCES dbo.DeviceGroups ( [id] )
) ;

CREATE TABLE dbo.DeviceAttributes
(
    [id]                        INT             NOT NULL    IDENTITY (1,1)
        CONSTRAINT      [PK_DeviceAttributes]   PRIMARY KEY CLUSTERED
    , [device_id]               INT             NOT NULL
        CONSTRAINT      [FK_DeviceAttributes_Devices]
        FOREIGN KEY REFERENCES dbo.Devices ( [id] )
    , [attribute_name]          VARCHAR(50)     NOT NULL
    , [attribute_value]         VARCHAR(50)     NULL
) ;
GO

INSERT
    INTO        dbo.Devices
                ( [device_name], [device_display_name], [device_location] )
    VALUES      ( 'dev001', 'Device 1', 'Location A' )
                , ( 'dev002', 'Device 2', 'Location A' )
                , ( 'dev003', 'Device 3', 'Location B' )
                , ( 'dev004', 'Device 4', 'Location B' ) ;

INSERT
    INTO        dbo.DeviceGroups
                ( [device_group_name] )
    VALUES      ( 'Group 1A' )  
                , ( 'Group 1B' ) ;

INSERT
    INTO        dbo.DeviceDeviceGroups
                ( [device_id], [group_id] )
    VALUES      ( 1, 1 )
                , ( 2, 1 )
                , ( 3, 1 )
                , ( 4, 1 ) ;

INSERT
    INTO        dbo.DeviceAttributes
                ( [device_id], [attribute_name], [attribute_value] )
    VALUES      ( 1, 'attrib #1', '0.10' )
                , ( 1, 'attrib #2', '0.02' )
                , ( 1, 'attrib #3', '0.07' )
                , ( 1, 'attrib #4', '0.02' )
                , ( 2, 'attrib #1', '0.16' )
                , ( 2, 'attrib #2', '0.05' )
                , ( 2, 'attrib #3', '0.12' )
                , ( 2, 'attrib #4', '0.04' )
                , ( 3, 'attrib #1', '0.15' )
                , ( 3, 'attrib #2', '0.05' )
                , ( 3, 'attrib #3', '0.07' )
                , ( 3, 'attrib #4', '0.06' )
                , ( 4, 'attrib #1', '0.10' )
                , ( 4, 'attrib #2', '0.03' )
                , ( 4, 'attrib #3', '0.07' )
                , ( 4, 'attrib #4', '0.03' ) ;
GO

令人討厭的是,該attribute_value列是字符串而不是數字,但並非所有屬性本質上都是數字。(這是供應商的架構。)

當我對錶執行平面查詢(使用 CTE)時,我得到了一整套屬性值。

詢問:

/* flat query */

USE [DeviceDatabase] ;
GO

DECLARE     @PrinterGroup   AS VARCHAR(50) ;
SET         @PrinterGroup   = 'Group 1A' ;

WITH cte_GroupedDevices AS
(
    SELECT          d.[id] AS [device_id]
                    , d.[device_name]
                    , d.[device_display_name]
                    , d.[device_location]
                    , dg.[device_group_name]
    FROM            dbo.Devices AS d
        INNER JOIN  dbo.DeviceDeviceGroups AS ddg
            ON      d.[id] = ddg.[device_id]
        INNER JOIN  dbo.DeviceGroups AS dg
            ON      ddg.[group_id] = dg.[id]
    WHERE           dg.[device_group_name] = @PrinterGroup
)
, cte_AttributedDevices AS
(
    SELECT          gd.[device_name]
                    , gd.[device_display_name]
                    , gd.[device_group_name]
                    , gd.[device_location]
                    , da.[attribute_name]                   
                    , CAST ( da.[attribute_value] AS DECIMAL (5,2) ) AS [attribute_value]
    FROM            cte_GroupedDevices AS gd
        INNER JOIN  dbo.DeviceAttributes AS da
            ON      gd.[device_id] = da.[device_id]
    WHERE           da.[attribute_name] IN
                    ( 
                        'attrib #1'
                        , 'attrib #2'
                        , 'attrib #3'
                        , 'attrib #4'
                    )
)
SELECT          [device_display_name]
                , [device_group_name]
                , [device_location]
                , [attribute_name]                  
                , [attribute_value]
FROM            cte_AttributedDevices
ORDER BY        [device_name] ASC, [attribute_name] ASC ;

結果:

device_display_name  |  device_group_name | device_location  |  attribute_name   |  attribute_value
---------------------------------------------------------------------------------------
Device 1                Group 1A            Location A          attrib #1           0.10
Device 1                Group 1A            Location A          attrib #2           0.02
Device 1                Group 1A            Location A          attrib #3           0.07
Device 1                Group 1A            Location A          attrib #4           0.02
Device 2                Group 1A            Location A          attrib #1           0.16
Device 2                Group 1A            Location A          attrib #2           0.05
Device 2                Group 1A            Location A          attrib #3           0.12
Device 2                Group 1A            Location A          attrib #4           0.04
Device 3                Group 1A            Location B          attrib #1           0.15
Device 3                Group 1A            Location B          attrib #2           0.05
Device 3                Group 1A            Location B          attrib #3           0.07
Device 3                Group 1A            Location B          attrib #4           0.06
Device 4                Group 1A            Location B          attrib #1           0.10
Device 4                Group 1A            Location B          attrib #2           0.03
Device 4                Group 1A            Location B          attrib #3           0.07
Device 4                Group 1A            Location B          attrib #4           0.03

但是,當我使用相同的 CTE 基礎針對相同的數據集執行PIVOT查詢(旋轉attribute_name列)時,所有屬性值都為 NULL。

詢問:

/* pivot query */

USE [DeviceDatabase] ;
GO

DECLARE     @PrinterGroup   AS VARCHAR(50) ;
SET         @PrinterGroup   = 'Group 1A' ;

WITH cte_GroupedDevices AS
(
    SELECT          d.[id] AS [device_id]
                    , d.[device_name]
                    , d.[device_display_name]
                    , d.[device_location]
                    , dg.[device_group_name]
    FROM            dbo.Devices AS d
        INNER JOIN  dbo.DeviceDeviceGroups AS ddg
            ON      d.[id] = ddg.[device_id]
        INNER JOIN  dbo.DeviceGroups AS dg
            ON      ddg.[group_id] = dg.[id]
    WHERE           dg.[device_group_name] = @PrinterGroup
)
, cte_AttributedDevices AS
(
    SELECT          gd.[device_name]
                    , gd.[device_display_name]
                    , gd.[device_group_name]
                    , gd.[device_location]
                    , da.[attribute_name]                   
                    , CAST ( da.[attribute_value] AS DECIMAL (5,2) ) AS [attribute_value]
    FROM            cte_GroupedDevices AS gd
        INNER JOIN  dbo.DeviceAttributes AS da
            ON      gd.[device_id] = da.[device_id]
    WHERE           da.[attribute_name] IN
                    ( 
                        'attrib #1'
                        , 'attrib #2'
                        , 'attrib #3'
                        , 'attrib #4'
                    )
)
SELECT          [device_display_name]
                , [device_group_name]
                , [device_location]
                , [attrib_1]
                , [attrib_2]
                , [attrib_3]
                , [attrib_4]
FROM            cte_AttributedDevices
PIVOT
(
    MIN ( [attribute_value] )
    FOR [attribute_name] IN
    (
        [attrib_1]
        , [attrib_2]
        , [attrib_3]
        , [attrib_4]
    )
) AS pvt
ORDER BY        [device_name] ASC ;

結果:

device_display_name  |  device_group_name | device_location  |  attrib_1  | attrib_2 |  attrib_3  | attrib_4
------------------------------------------------------------------------------------------------------------
Device 1                Group 1A            Location A          NULL        NULL        NULL        NULL
Device 2                Group 1A            Location A          NULL        NULL        NULL        NULL
Device 3                Group 1A            Location B          NULL        NULL        NULL        NULL
Device 4                Group 1A            Location B          NULL        NULL        NULL        NULL

PIVOT在查詢段中嘗試了許多不同的函數-- MIN, MAX, SUM, AVG-- 所有這些都會產生相同的結果。

我曾嘗試將數據轉儲到臨時表中——一個在attribute_value上具有數字數據類型的表——但它產生相同的結果,無論是平面查詢還是透視查詢。

我已經在基表和臨時表中NOT NULLattribute_value列進行約束同樣的結果。

我究竟做錯了什麼?

約翰·卡佩萊蒂

這是一個工作示例。注意:@YourResults 是您實際初始查詢的替代品。

我沒有看到你轉換attrib #1到的任何邏輯attrib_1

例子

Declare @YourResults Table ([device_display_name] varchar(50),[device_group_name] varchar(50),[device_location] varchar(50),[attribute_name] varchar(50),[attribute_value] varchar(50))
Insert Into @YourResults Values 
 ('Device 1','Group 1A','Location A','attrib #1',0.10)
,('Device 1','Group 1A','Location A','attrib #2',0.02)
,('Device 1','Group 1A','Location A','attrib #3',0.07)
,('Device 1','Group 1A','Location A','attrib #4',0.02)
,('Device 2','Group 1A','Location A','attrib #1',0.16)
,('Device 2','Group 1A','Location A','attrib #2',0.05)
,('Device 2','Group 1A','Location A','attrib #3',0.12)
,('Device 2','Group 1A','Location A','attrib #4',0.04)
,('Device 3','Group 1A','Location B','attrib #1',0.15)
,('Device 3','Group 1A','Location B','attrib #2',0.05)
,('Device 3','Group 1A','Location B','attrib #3',0.07)
,('Device 3','Group 1A','Location B','attrib #4',0.06)
,('Device 4','Group 1A','Location B','attrib #1',0.10)
,('Device 4','Group 1A','Location B','attrib #2',0.03)
,('Device 4','Group 1A','Location B','attrib #3',0.07)
,('Device 4','Group 1A','Location B','attrib #4',0.03)
 
Select * 
 From @YourResults
 Pivot (min([attribute_value]) for [attribute_name] IN (
                                                         [attrib #1]
                                                       , [attrib #2]
                                                       , [attrib #3]
                                                       , [attrib #4]
                                                       ) ) Pvt

結果

在此處輸入圖片說明

編輯 - 如果你想要 [attrib_1]你可以指定列並分配別名。

Select [device_display_name]
      ,[device_group_name]
      ,[device_location]
      ,[attrib_1] = [attrib #1]
      ,[attrib_2] = [attrib #2]
      ,[attrib_3] = [attrib #3]
      ,[attrib_4] = [attrib #4]
 From @YourResults
 Pivot (min([attribute_value]) for [attribute_name] IN (
                                                         [attrib #1]
                                                       , [attrib #2]
                                                       , [attrib #3]
                                                       , [attrib #4]
                                                       ) ) Pvt

在此處輸入圖片說明

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

為什麼當列表包含零時 foldr 函數給我一個否定的結果?

當列表包含零時,為什麼 foldr 函數給我一個否定結果?

為什麼 Java 在使用 List.toArray 時向數組插入 null

為什麼 getItem 在我的代碼中使用 asyncStorage 返回 'Promise { "_U": 0, "_V": 0, "_W": null, "_X": null, }'?

為什麼在 Postgres 中使用空表,如果我使用 BEFORE INSERT,:NEW: 變量為 NULL?

為什麼我的 document.querySelector 返回 null?

為什麼在 showDialog 之後使用 <Null>?

為什麼 typescript 在實現抽象函數時會忽略嚴格的 null 檢查?

為什麼我們不使用驗證數據集而不是測試數據集?

SSRS - 如果您的查詢結果為 Null,如何使用表達式返回空白作為顯示

使用PIVOT的NULL字段

為什麼 MySQL 查詢不更新數據?

為什麼在空列上使用 ORDER BY 的 TOP 1 結果集顯示與 TOP 5 不同的結果?

為什麼 IoAllocateErrorLogEntry 返回 null?

為什麼我的數組在向其附加值後返回 null 或顯示一個空數組

為什麼即使分配給另一個相同類型的結構,該結構仍保持為 NULL?

為什麼 $Null 驗證在 powershell 函數中失敗?

為什麼數組中的每個元素都以“null”開頭?

為什麼去相關查詢沒有產生預期的結果?

為什麼 jpa 自定義查詢返回更多結果

Python將數據庫查詢結果導出為日曆JS的JSON

為什麼我在 SVG 上無法讀取 null 的屬性“tagName”?

為什麼改變數據類型會改變整個結果?

為什麼我不能使用 searchBar 顯示來自 API 的數據?

為什麼重新定義生成器中使用的變量會產生奇怪的結果?

為什麼我有一個錯誤:返回 API 數據時無法讀取未定義的屬性“結果”?

ADF 數據流:將 null 分配給否定結果

為什麼在檢查 NULL 條件時會出現 FILE 指針錯誤?

使用 sqlite3.connect 查詢數據庫並檢查匹配結果