首页 > 解决方案 > 从具有特殊编号的同一行输出两行

问题描述

我有一张桌子

ID Company Product Weight Price Date
-- ------- ------- ------ ----- ----
1  555     blanket  3     10    20201207
2  555     blanket  7     45    20201208
3  555     blanket  8     33    20201208
4  123     pillow   7     66    20200901
5  999     pillow   5     55    20200902

我需要这样的输出

Company|Product|Unit Type|Unit Amount|Numbering
------- ------- --------- ----------  ----
555     blanket weight    3           2020-1
555     blanket price     10          2020-1
555     blanket weight    7           2020-2
555     blanket price     45          2020-2
555     blanket weight    8           2020-3
555     blanket price     33          2020-3
123     pillow  weight    7           2020-1
123     pillow  price     66          2020-1
999     pillow  weight    5           2020-1
999     pillow  price     55          2020-1

我有这个查询,但在 WHERE 子句"The multi part identifier p1.id could not be bound"附近出现错误。也不确定如何进行编号,每个产品和公司最多 10 个,并且 2020 是从日期中提取的。似乎 CROSS APPLY 可以解决主要问题,编号可以用 ROW_NUMBER() 解决,但我还不能解决它。

SELECT 
    p1.company, 
    p1.product, 
    'weight', 
    p1.weight,
    (CONVERT(VARCHAR(4), p1.date, 112)) + '-',
FROM Products p1
UNION ALL
SELECT 
    p2.company, 
    p2.product, 
    'price', 
    p2.price,
    (CONVERT(VARCHAR(4), p2.date, 112)) + '-',
FROM Products p2
WHERE p1.id=p2.id
ORDER BY company

标签: sqlsql-serversql-server-2012unpivotlateral-join

解决方案


在 SQL Server 中,您可以使用以下命令简单有效地取消透视cross apply

select t.company, t.product, x.unit_type, x.amount, t.date
from mytable t
cross apply (values ('weight', weight), ('price', price)) as x(unit_type, amount)

您可以使用以下命令生成序列号dense_rank()

select t.company, t.product, x.unit_type, x.amount, 
    concat(year(t.date), '-', dense_rank() over(partition by t.company, t.product, year(t.date) order by t.date, t.id)) as rn
from mytable t
cross apply (values ('weight', weight), ('price', price)) as x(unit_type, amount)

推荐阅读