SQL Server:根据列值将行拆分为多行

时间:2019-12-12 11:41:03

标签: sql sql-server

我有一个有关根据列值拆分行的问题

我的示例数据集是:

id   ExpenseType   Price
------------------------
 1   Car           100
 2   Hotel          50

我想将具有某些费用类型(例如Car)的行拆分为两行。其他应保持为一行。

First row Price *70 
Second Row Price *30 

返回的数据集应为

id   ExpenseType  Price
-----------------------
 1   Car           70 
 1   Car           30 
 2   Hotel         50

感谢您的预先回答

3 个答案:

答案 0 :(得分:2)

如果您想分配比汽车更多的费用类型,可以使用:

WITH r AS (
    SELECT 'Car' AS ExpenseType, 0.7 AS Ratio
    UNION SELECT 'Car' AS ExpenseType, 0.3 AS Ratio
    -- add more ExpenseTypes/Ratios here
)
SELECT
    t.id,
    t.ExpenseType,
    t.Price * ISNULL(r.Ratio, 1.0) AS Price
FROM
    your_table t
    LEFT OUTER JOIN r ON t.ExpenseType = r.ExpenseType

答案 1 :(得分:1)

一种简单的方法使用union all

select id, expensetype, price
from t
where expensetype <> 'Car'
union all
select id, expensetype, price * 0.7
from t
where expensetype = 'Car'
union all
select id, expensetype, price * 0.3
from t
where expensetype = 'Car';

这不是最有效的方法。为此,具有过滤逻辑的cross apply更好:

select t.id, v.*
from t cross apply
     (values (NULL, price), ('Car', price * 0.3), ('Car', price * 0.7)
     ) v(expensetype, price)
where v.expensetype = t.expense_type or
      v.expensetype <> 'Car' and t.expense_type is null;

答案 2 :(得分:1)

一种不太简单的方法是使用OUTER APPLY

CREATE TABLE YourSampleData
(
  Id INT IDENTITY(1,1) PRIMARY KEY,
  ExpenseType VARCHAR(30) NOT NULL,
  Price INT NOT NULL DEFAULT 0
);
INSERT INTO YourSampleData 
(ExpenseType, Price) VALUES
 ('Car', 100)
,('Hotel', 50)
,('Gold', 1)
;
SELECT Id, ExpenseType
, COALESCE(a.Price, t.Price) AS Price
FROM YourSampleData t
OUTER APPLY
(
  SELECT Price * Perc AS Price
  FROM (VALUES 
    ('Car',0.3E0), ('Car',0.7E0)
   ,('Gold',1.618E0)
  ) AS v(ExpType, Perc)
  WHERE t.ExpenseType = v.ExpType
) a
GO
Id | ExpenseType | Price
-: | :---------- | ----:
 1 | Car         |    30
 1 | Car         |    70
 2 | Hotel       |    50
 3 | Gold        | 1.618

db <>提琴Atomic design pattern