簡體   English   中英

將列名轉置為行並將值放在單獨的列中

[英]Transpose column names to rows and put values in seperate column

我有下表,您也可以在此處SQL fiddle找到

CREATE TABLE Flows (
    Product TEXT,
    Inbound_Date DATE,
    Outbound_Date DATE,
    Return_Date DATE,
    Quantity VARCHAR(255)
);

INSERT INTO Flows
(Product, Inbound_Date, Outbound_Date, Return_Date, Quantity)
VALUES 

("Product A", "2019-01-01", NULL, NULL, "400"),
("Product A", NULL, "2019-05-08", NULL, "200"),
("Product A", NULL, NULL, "2019-06-25", "600"),

("Product B", "2019-03-08", NULL, NULL, "380"),
("Product B", NULL, "2019-03-15", NULL, "120"),
("Product B", NULL, NULL, "2019-04-17", "610");

我使用以下 SQL 從表中獲取值:

SELECT Product, Inbound_Date, Outbound_Date, Return_Date, sum(Quantity)
FROM Flows
GROUP BY 1,2,3,4;

到目前為止,所有這些都運行良好。


但是,現在我想實現日期顯示在名為FLow_Date列中。
結果應如下所示:

Product          Date_Type            Flow_Date
Product A        Inbound_Date        2019-01-01
Product A        Oubound_Date        2019-05-08
Product A        Return_Date         2019-06-25
Product B        Inbound_Date        2019-03-08
Product B        Outbound_Date       2019-03-15
Product B        Return_Date         2019-04-17

我需要在代碼中更改什么才能使其正常工作?

您可以使用coalesce()case表達式:

select
    product,
    case 
        when inbound_date is null  then 'inbound_date' 
        when outbound_date is null then 'outbound_date'
        when return_date is null   then 'return_date'
    end date_type,
    coalesce(inbound_date, outbound_date, return_date) flow_date
from mytable

如果你想在你的聚合查詢中使用這個:

select
    product,
    case 
        when inbound_date is null  then 'inbound_date' 
        when outbound_date is null then 'outbound_date'
        when return_date is null   then 'return_date'
    end date_type,
    coalesce(inbound_date, outbound_date, return_date) flow_date,
    sum(quantity) sum_quantity
from mytable
group by 
    product,
    date_type,
    flow_date

我認為你只需要case表達式:

select f.product,
       (case when inbound_date is not null then 'inbound_date' 
             when outbound_date is not null then 'outbound_date'
             when return_date is not null then 'return_date'
        end) date_type,
       (case when inbound_date is not null then inbound_date
             when outbound_date is not null then outbound_date
             when return_date is not null then return_date
        end) as flow_date
from flows f;

如果每行可以有多個非NULL值,這會變得更加復雜。

在這種情況下, union all是一個足夠簡單的方法

select fd.*
from ((select f.product, 'inbound_date' as date_type, inbound_date as flow_date
       from flows f
      ) union all
      (select f.product, 'outbound_date' as date_type, outbound_date as flow_date
       from flows f
      ) union all
      (select f.product, 'return_date' as date_type, return_date as flow_date
       from flows f
      )
     ) fd
where flow_date is not null;

這不一定是最有效的方法(在這種情況下),但效果很好。 如果flows確實是一種觀點,那么替代方案可能是首選。

暫無
暫無

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

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