SQL 列的排列

SQL Permutation of Columns

我有一件商品 table 看起来像这样:

store_id.   industry_code    amt_age_18_24    amt_age_25-34    amt_men    amt_women
       1             1000              100               20         80           40
       2             2000              100              100        130           70

我想做的是找到每家商店按年龄和性别排列的购买情况。像这样,每一行都是唯一的:

store_id.   industry_code    amt_age_18_24    amt_age_25-34    amt_men    amt_women
       1             1000              100             NULL         80          NULL
       1             1000              100             NULL        NULL           40
       1             1000              NULL            20           80          NULL
       1             1000              NULL            20          NULL           80
       2             2000              100             NULL        130          NULL
       2             2000              100             NULL        NULL           70
       2             2000              NULL            100         130          NULL
       2             2000              NULL            100         NULL           70

最好的方法是什么?自我加入?

这看起来像 union all:

select store_id, instrustry_code, amt_age_18_24, null as amt_age_25_34, amt_men, null as amt_women
from t
union all
select store_id, instrustry_code, amt_age_18_24, null as amt_age_25_34, null as amt_men, amt_women
from t
union all
. . . 

这是一种使用 cross join 和包含“列掩码”的派生 table 的方法:

select 
    t.store_id, 
    t.industry_code, 
    t.amt_age_18_24 * x.amt_age_18_24 as amt_age_18_24,
    t.amt_age_25_34 * x.amt_age_25_34 as amt_age_25_34,
    t.amnt_men      * x.amnt_men      as amnt_men,
    t.amt_women     * x.amt_women     as amt_women
from mytable t
cross join (
    select 1 as amt_age_18_24, null as amt_age_25_34, 1 as amnt_men, null as amt_women
    union all select 1, null, null, 1
    union all select null, 1, 1, null
    union all select null, 1, null, 1
) x

优点是不需要多次扫描 table,这与 union all 方法相反。

您可以根据需要为每个排列使用并集:

select store_id, instrustry_code, amt_age_18_24, null as amt_age_25_34, amt_men, null as amt_women
from t
union all
select store_id, instrustry_code, amt_age_18_24, null as amt_age_25_34, null as amt_men, amt_women
from t

并根据需要对任意多的列执行此操作