如何将两行合并为一个并允许空值

时间:2013-03-20 17:14:47

标签: sql-server

我在这里看到了类似的例子和解决方案让我走得这么远(谢谢),但无法弄清楚最后一步。理想情况下,该解决方案可有效地组合数十万行。

基本上我有一个价格数据表,每个项目有1或2行不同类型的价格数据 - 价格类型1和价格类型2.我想最终得到一个结合了2个价格的表/视图在一行上,但保持每一行的相对位置,并允许价格2数据为空。

所以,如果我有这些数据:

CREATE TABLE Table1 ([Name] varchar(2), [type] char(1), [price] decimal(10,2));

INSERT INTO Table1 ([Name], [type], [price])
VALUES
    ('a', '1', '1.20'),
    ('a', '2', '1.25'),
    ('a1','1', '2.99'),
    ('b', '1', '2.20'),
    ('b', '2', '2.25'),
    ('b1','2', '3.99'),
    ('c', '1', '3.20'),
    ('c', '2', '3.25'),
    ('d', '1', '4.20'),
    ('d', '2', '4.25');

我可以运行这个SQL:

select name, [1] price_1, [2] price_2
from
(
  select name,
         price,
         row_number() over (partition by name
                            order by type asc) rn
    from table1
) o
pivot (min(price) for rn in ([1], [2])) p

我得到以下输出,这对我想要的不太合适。

NAME PRICE_1  PRICE_2
a    1.2      1.25
a1   2.99     (null)
b    2.2      2.25
b1   3.99     (null)
c    3.2      3.25
d    4.2      4.25

我需要的是a1和b1行在price_1列中的空值和price_2列中的价格。

3 个答案:

答案 0 :(得分:3)

完全加入可以做到这一点......

Insert newTable(name, PriceA, PriceB)
Select coalesce(a.Name, b.Name) Name,
    a.Price, b.price
From oldTable a Full Join oldTable b
   On b.name = a.Name
       and a.Type = [PricetTypeA]
       and b.Type = [PricetTypeB]

或者,如果pricetype是字符串='A'或'B',

Insert newTable(name, PriceA, PriceB)
Select coalesce(a.Name, b.Name) Name,
    a.Price, b.price
From oldTable a Full Join oldTable b
   On b.name = a.Name
       and a.Type = 'A'
       and b.Type = 'B'

答案 1 :(得分:1)

Charles给了我一个使用完全加入的想法,在玩完之后我就开始工作了。

Select coalesce(a.Name, b.name) as name, a.Price as price1, b.price as price2
From      (select name, price from table1 where type='1') a
full Join (select name, price from table1 where type='2') b
On b.name = a.Name

这可以正常使用视图。

很高兴有任何其他建议和意见。

答案 2 :(得分:0)

我真的不明白你使用ROW_NUMBER的原因。您可以改为使用type列:

select name, [1] price_1, [2] price_2
from
(
  select name,
         price,
         row_number() over (partition by name
                            order by type asc) type rn
    from table1
) o
pivot (min(price) for rn in ([1], [2])) p

SQL Fiddle demo