2016-03-08 78 views
1

我有两个表(基表和数据表),我正在使用OUTER APPLY合并以获得结果。将列显示为复杂Select语句中的行sql

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 | 
+------+------------+-------------+-------+ 
+0

这不是MySQL的。这是TSQL .. Stackoverflow自动将它标记为'mysql',不知道为什么。 – Shanka

+1

对不起,我知道为什么。我修好了它。谢谢。 – Shanka

+0

如果您要提出与SQL相关的问题,请参阅此文章:[*如何在公共论坛上发布T-SQL问题*](http://spaghettidba.com/2015/04/24/how -to-post-at-sql-question-on-a-public-forum /) –

回答

1

你可以试试这个:

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' 
+0

谢谢!这有助于。 – Shanka

1
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子句中的那些。

1

最简单的方法是在你的应用外表UNPIVOT:

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