เป็นไปได้ที่จะ PIVOT ในคำสั่ง LIKE


9

เป็นไปได้ไหมที่จะจัดกลุ่มตามองค์ประกอบ (ดังในCOLUMN LIKE='Value%') ในPIVOTตาราง? ฉันมีตาราง [DBT] [สถานะ] ซึ่งมีสถานะต่าง ๆ (ของฐานข้อมูลอินสแตนซ์ ฯลฯ ) และไม่ต้องการหมุน / ค้นหาค่า PROD และการทดสอบทั้งหมดเป็นค่าเดียว

เช่นแทนที่จะมีคอลัมน์สำหรับสถานะProd, Prod ACC, Prod APP.. ฯลฯ ฉันจะมีเพียงหนึ่งคอลัมน์ที่มีค่าสำหรับและName LIKE 'Prod%'Name LIKE 'Test%'

สิ่งที่ฉันมี:

นิยามของตาราง

CREATE TABLE [DBT].[Status](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](50) NOT NULL,
 CONSTRAINT [PK_Status] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80) ON [PRIMARY],
 CONSTRAINT [IX_Status] UNIQUE NONCLUSTERED 
(
    [Name] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80) ON [PRIMARY]
) ON [PRIMARY]

GO

ค่าของตาราง

INSERT INTO [DBT].[Status]
(
    -- ID -- this column value is auto-generated
    Name
)
VALUES
('Test ACC'),
('Test APP'),
('Test DBA'),
('Prod ACC'),
('Prod APP'),
('Prod DBA'),
('Prod'),
('Test'),
('Migrated'),
('Offline'),
('Reserved')

ตารางสถานะ Pivoted

SELECT 'Database Status' AS [DB Status], 
[1] AS [Test ACC], [2] AS [Test APP], [3] AS [Test DBA], [4] AS [Prod ACC], [5] AS [Prod APP], [6] AS [Prod DBA], [7] AS [Prod], [8] AS [Test], [9] AS [Migrated], [10] AS [Offline], [11] AS [Reserved] 
FROM 
(
    SELECT ID, Name  FROM [DBT].[Status]
) AS Source
PIVOT
(
    COUNT(Name) FOR ID IN ([1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11])
) AS PivotTable

จนถึงตอนนี้

DB Status       Test ACC    Test APP    Test DBA    Prod ACC    Prod APP    Prod DBA    Prod        Test        Migrated    Offline     Reserved
--------------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
Database Status 1           1           1           1           1           1           1           1           1           1           1

DB <> ซอ

dbfiddleเพื่อให้ห่างไกล

คำถาม

แทนที่จะมีหลายแถวสำหรับค่าTest... และProd....ค่าต่าง ๆฉันต้องการจัดกลุ่มให้คล้ายกับตัวอย่างต่อไปนี้:

DB Status       | Test | Prod | Migrated | Offline | Reserved   
--------------- | ---- | ---- | -------- | ------- | --------
Database Status |    4 |    4 |        1 |       1 |        1

ฉันไม่มีเงื่อนงำใด ๆ เกี่ยวกับการแก้ไขคำถามของฉัน (พูดตามตรงฉันเพิ่งเข้าใจ PIVOT เมื่อวานนี้หลังจากการลองผิดลองถูกมากมาย)

คำถามนี้เกี่ยวข้องกับคำถามอย่างคร่าว ๆวิธีสร้างผลรวม / นับของรายการที่จัดกลุ่มผ่านหลายตารางที่ฉันถามไปแล้ว ตาราง [DBT] [Instance] และ [DBT] [ฐานข้อมูล] มีคอลัมน์ที่มี [StatusID] ซึ่งสอดคล้องกับตารางที่เรากำลังดูอยู่ในขณะนี้

คำตอบ:


11

SUM (กรณี

สำหรับชื่อจำนวน จำกัด คุณสามารถใช้ SUM (โซลูชัน CASE ด้วยวิธีนี้:

SELECT 
    'Database status' as [DB Status],
    SUM(CASE WHEN Name LIKE 'Test%' THEN 1 ELSE 0 END) As Test,
    SUM(CASE WHEN Name LIKE 'Prod%' THEN 1 ELSE 0 END) AS Prod,
    SUM(CASE WHEN Name = 'Migrated' THEN 1 ELSE 0 END) AS Migrated,
    SUM(CASE WHEN Name = 'Offline' THEN 1 ELSE 0 END) AS Offline,
    SUM(CASE WHEN Name = 'Reserved' THEN 1 ELSE 0 END) AS Reserved
FROM 
    [Status];

หมุน

หากมีรายการชื่อที่กว้างขวาง แต่มีเพียงไม่กี่รายการเท่านั้นที่ต้องเขียนใหม่คุณสามารถดูแลรักษาโซลูชัน PIVOT:

SELECT 'Database Status' AS [DB Status],
[Test], [Prod], [Migrated], [Offline], [Reserved]
FROM
(
    SELECT 
        ID, 
        CASE
            WHEN Name LIKE 'Test%' THEN 'Test'
            WHEN Name LIKE 'Prod%' THEN 'Prod'
            ELSE Name
        END AS Name
    FROM 
        [Status]
) AS Source
PIVOT
(
    COUNT(ID) FOR Name IN ([Test], [Prod], [Migrated], [Offline], [Reserved])
) AS PivotTable;

db <> ซอที่นี่

แบบสอบถามแบบไดนามิก

หากคุณรู้สึกเกียจคร้านและไม่ต้องการเขียนชื่อคอลัมน์ทั้งหมดคุณสามารถใช้การสืบค้นแบบไดนามิก:

DECLARE @cols nvarchar(max);

SET @cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(CASE WHEN Name LIKE 'Test%' THEN 'Test'
                                                    WHEN Name LIKE 'Prod%' THEN 'Prod'
                                                    ELSE Name END)
                   FROM [Status]
                   FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '');

DECLARE @cmd nvarchar(max);

SET @cmd = 
'SELECT ''Database Status'' AS [DB Status],' + @cols + ' FROM
    (SELECT 
        ID, 
        CASE
            WHEN Name LIKE ''Test%'' THEN ''Test''
            WHEN Name LIKE ''Prod%'' THEN ''Prod''
            ELSE Name
        END AS Name
    FROM 
        [Status]
) AS Source
PIVOT
(
    COUNT(ID) FOR Name IN (' + @cols + ')
) PVT'

EXEC(@cmd);

db <> ซอที่นี่


7

ฉันคิดว่ามันเป็นเรื่องสำคัญที่จะต้องแยกงานสองอย่างที่คุณพยายามทำในขั้นตอนเดียวออกจากกัน

  1. การจัดหมวดหมู่
  2. การแปลง

สำหรับการจำแนกข้อมูลสัญชาตญาณของฉันที่นี่คือการแนะนำตารางการค้นหาเพื่อจับคู่ระเบียนกับแม่อย่างเข้มงวด เช่น

CREATE TABLE StatusType (
  ID     INT         IDENTITY PRIMARY KEY,
  [Name] VARCHAR(10) NOT NULL UNIQUE
);
GO
ALTER TABLE [Status] 
  ADD StatusTypeID INT NOT NULL 
    DEFAULT 1
    FOREIGN KEY REFERENCES StatusType (ID) ;

... โดยที่การบันทึกของเมล็ดพันธุ์ในStatusType( ID= 1 สำหรับStatus.StatusTypeIDค่าเริ่มต้น) เป็นตัวยึดตำแหน่งชื่อ "ไม่ทราบ" หรือคล้ายกัน

เมื่อข้อมูลการค้นหาถูก seeded และมีการอัพเดทฐานข้อมูลด้วยปุ่มที่ถูกต้องคุณสามารถหมุนไปที่เนื้อหาหัวใจของคุณ

select 'Database Status' AS [DB Status],
    [Test], [Prod], [Migrated], [Offline], [Reserved]
from (
    select s.ID,
           st.Name as StatusTypeName
    from status s
    join statusType st on st.ID = s.StatusTypeID
) as Source
pivot (
    count(ID) for StatusTypeName in ([Test],[Prod],[Migrated],[Offline],[Reserved],[Unknown])
) as pvt;

dbfiddle เต็มรูปแบบ


ขอบคุณสำหรับการแก้ปัญหาของคุณมันเป็นทางออกที่ดีงาม อย่างไรก็ตามในปัจจุบันฉันไม่สามารถแก้ไขคำจำกัดความของตารางที่มีอยู่หรือเพิ่มลงในการออกแบบฐานข้อมูล
John aka hot2use

1
เลือกข้อมูลลงในตารางชั่วคราวก่อนซึ่งเป็นวิธีที่คุณสามารถควบคุมข้อมูลได้ วางล่อลวงหลังจากที่คุณเลือกจากมันเพื่อแสดงถ้าคุณต้องการ เมื่อแบบสอบถามของคุณเสร็จสิ้นคุณสามารถอบเป็นขั้นตอนการจัดเก็บที่ดูแลโดยอัตโนมัติเลือกเป็นล่อลวงและวางหลังจากคุณเสร็จสิ้น
khaoliang
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.