在复杂的 Select 语句中将列显示为行 - sql
Displaying columns as rows in a complex Select statement - sql
我有两个 table(一个基础 table 和一个数据 table),我正在使用 OUTER APPLY 合并它们以获得结果。
tblBase
看起来像这样:
+------+------+
| IDnu | Name |
+------+------+
| 1 | abc |
| 2 | cde |
| 3 | efg |
| 4 | rfl |
+------+------+
tblData
是这样的:
+------+--------+--------+--------+-------------+
| IDNu | Price1 | Price2 | Price3 | ProductType |
+------+--------+--------+--------+-------------+
| 1 | 10 | 15 | 20 | Old |
| 2 | 10 | 20 | 30 | Refurbished |
| 3 | 20 | 30 | 40 | New |
| 1 | 20 | 15 | 20 | New |
| 2 | 20 | 10 | 30 | Old |
+------+--------+--------+--------+-------------+
我当前根据几个条件计算 tblData
的查询如下:
Select IDNu, Name, t2.PNew, t2.POld FROM tblBase as t1
OUTER APPLY
(
SELECT
SUM (CASE WHEN ProductType = 'New' THEN Price1 + Price2 ELSE 0 END) AS PNew,
SUM (CASE WHEN ProductType = 'Old' THEN Price2 + Price3 ELSE 0 END) AS POld
FROM tblData
WHERE IDNu = t1.IDNu
GROUP BY IDNu
) t2
以上查询结果为:
+------+------------+------+------+
| IDNu | Name | PNew | POld |
+------+------------+------+------+
| 1 | abc | 35 | 35 |
| 2 | cde | 0 | 40 |
| 3 | efg | 50 | 0 |
| 4 | rfl | NULL | NULL |
+------+------------+------+------+
现在我的问题是,不是在两列中显示 PNew 和 Pold,而是在行中显示它们? 像这样:
+------+------------+-------------+-------+
| IDNu | Name | ProductType | Price |
+------+------------+-------------+-------+
| 1 | abc | PNew | 35 |
| 2 | cde | PNew | 0 |
| 3 | efg | PNew | 50 |
| 4 | rfl | PNew | NULL |
| 1 | abc | POld | 35 |
| 2 | cde | POld | 40 |
| 3 | efg | POld | 0 |
| 4 | rfl | POld | NULL |
+------+------------+-------------+-------+
select b.IDNu, b.Name, pt.ProductType, d.Price
from
tblBase as b cross join (select 'New' ProductType union all select 'Old') pt
left outer join
(
select
ProductType,
sum(case ProductType
when 'New' then Price1 + Price2
when 'Old' then Price2 + Price3 end) as Price
from tblData
where ProductType in ('New', 'Old') /* not strictly necessary but maybe faster */
group by IDNu, ProductType
) d
on d.IDNu = p.IDNu and d.ProductType = pt.ProductType
order by b.IDNu, pt.ProductType
或...
select
b.IDNu, b.Name, pt.ProductType,
sum(case pt.ProductType
when 'New' then d.Price1 + d.Price2
when 'Old' then d.Price2 + d.Price3 end) as Price
from
tblBase as b
cross join
(select 'New' ProductType union all select 'Old') pt
left outer join
tblData d on d.IDNu = p.IDNu and d.ProductType = pt.ProductType
group by b.IDNu, pt.ProductType
order by b.IDNu, pt.ProductType
在您的输出中,您在没有数据的地方混合了一些零和空输出。当然,翻译这些空值的正常方法是使用 coalesce()
。你也有 "PNew" 和 "POld" 作为你的输出值,但我不确定这是故意的。一个简单的 case
将处理输出 select
子句中的那些。
你能试试这个吗:
SELECT tblBase.*, 'PNew' as ProductType, tblData.Price1 + tblData.Price2 as Price
FROM tblBase left join `tblData`
On tblBase.IDnu = tblData.IDnu AND tblData.ProductType = 'New'
UNION ALL
SELECT tblBase.*, 'POld' as ProductType, tblData.Price3 + tblData.Price2 as Price
FROM tblBase left join `tblData`
On tblBase.IDnu = tblData.IDnu AND tblData.ProductType = 'Old'
最简单的方法是在应用的外部旋转 table:
Select
IDNu,Name,t2.ProductType,t2.Price
FROM
tblBase as t1
OUTER APPLY (
SELECT ProductType='New',SUM(Price1+Price2) AS Price
FROM tblData
WHERE IDNu=t1.IDNu AND ProductType='New'
UNION ALL
SELECT ProductType='Old',SUM(Price2+Price3) AS Price
FROM tblData
WHERE IDNu=t1.IDNu AND ProductType='Old'
) t2
我有两个 table(一个基础 table 和一个数据 table),我正在使用 OUTER APPLY 合并它们以获得结果。
tblBase
看起来像这样:
+------+------+
| IDnu | Name |
+------+------+
| 1 | abc |
| 2 | cde |
| 3 | efg |
| 4 | rfl |
+------+------+
tblData
是这样的:
+------+--------+--------+--------+-------------+
| IDNu | Price1 | Price2 | Price3 | ProductType |
+------+--------+--------+--------+-------------+
| 1 | 10 | 15 | 20 | Old |
| 2 | 10 | 20 | 30 | Refurbished |
| 3 | 20 | 30 | 40 | New |
| 1 | 20 | 15 | 20 | New |
| 2 | 20 | 10 | 30 | Old |
+------+--------+--------+--------+-------------+
我当前根据几个条件计算 tblData
的查询如下:
Select IDNu, Name, t2.PNew, t2.POld FROM tblBase as t1
OUTER APPLY
(
SELECT
SUM (CASE WHEN ProductType = 'New' THEN Price1 + Price2 ELSE 0 END) AS PNew,
SUM (CASE WHEN ProductType = 'Old' THEN Price2 + Price3 ELSE 0 END) AS POld
FROM tblData
WHERE IDNu = t1.IDNu
GROUP BY IDNu
) t2
以上查询结果为:
+------+------------+------+------+
| IDNu | Name | PNew | POld |
+------+------------+------+------+
| 1 | abc | 35 | 35 |
| 2 | cde | 0 | 40 |
| 3 | efg | 50 | 0 |
| 4 | rfl | NULL | NULL |
+------+------------+------+------+
现在我的问题是,不是在两列中显示 PNew 和 Pold,而是在行中显示它们? 像这样:
+------+------------+-------------+-------+
| IDNu | Name | ProductType | Price |
+------+------------+-------------+-------+
| 1 | abc | PNew | 35 |
| 2 | cde | PNew | 0 |
| 3 | efg | PNew | 50 |
| 4 | rfl | PNew | NULL |
| 1 | abc | POld | 35 |
| 2 | cde | POld | 40 |
| 3 | efg | POld | 0 |
| 4 | rfl | POld | NULL |
+------+------------+-------------+-------+
select b.IDNu, b.Name, pt.ProductType, d.Price
from
tblBase as b cross join (select 'New' ProductType union all select 'Old') pt
left outer join
(
select
ProductType,
sum(case ProductType
when 'New' then Price1 + Price2
when 'Old' then Price2 + Price3 end) as Price
from tblData
where ProductType in ('New', 'Old') /* not strictly necessary but maybe faster */
group by IDNu, ProductType
) d
on d.IDNu = p.IDNu and d.ProductType = pt.ProductType
order by b.IDNu, pt.ProductType
或...
select
b.IDNu, b.Name, pt.ProductType,
sum(case pt.ProductType
when 'New' then d.Price1 + d.Price2
when 'Old' then d.Price2 + d.Price3 end) as Price
from
tblBase as b
cross join
(select 'New' ProductType union all select 'Old') pt
left outer join
tblData d on d.IDNu = p.IDNu and d.ProductType = pt.ProductType
group by b.IDNu, pt.ProductType
order by b.IDNu, pt.ProductType
在您的输出中,您在没有数据的地方混合了一些零和空输出。当然,翻译这些空值的正常方法是使用 coalesce()
。你也有 "PNew" 和 "POld" 作为你的输出值,但我不确定这是故意的。一个简单的 case
将处理输出 select
子句中的那些。
你能试试这个吗:
SELECT tblBase.*, 'PNew' as ProductType, tblData.Price1 + tblData.Price2 as Price
FROM tblBase left join `tblData`
On tblBase.IDnu = tblData.IDnu AND tblData.ProductType = 'New'
UNION ALL
SELECT tblBase.*, 'POld' as ProductType, tblData.Price3 + tblData.Price2 as Price
FROM tblBase left join `tblData`
On tblBase.IDnu = tblData.IDnu AND tblData.ProductType = 'Old'
最简单的方法是在应用的外部旋转 table:
Select
IDNu,Name,t2.ProductType,t2.Price
FROM
tblBase as t1
OUTER APPLY (
SELECT ProductType='New',SUM(Price1+Price2) AS Price
FROM tblData
WHERE IDNu=t1.IDNu AND ProductType='New'
UNION ALL
SELECT ProductType='Old',SUM(Price2+Price3) AS Price
FROM tblData
WHERE IDNu=t1.IDNu AND ProductType='Old'
) t2