我的SQL数据库上有表格
Code | Ordered | Cut01 | Cut02 | Cut03 | Confirmed
--------------------------------------------------
8832 10 1 1 3 5
8821 12 0 1 2 9
8122 20 10 0 0 10
8901 11 0 8 1 2
如何为每个Code
分隔行,其中有Cuts*
个<> 0
并将自己增加为:
Code | Ordered | Cut01 | Cut02 | Cut03 | Confirmed
--------------------------------------------------
8832 1 1 0 0 0
8832 1 0 1 0 0
8832 8 0 0 3 5
--------------------------------------------------
8821 1 0 1 0 0
8821 11 0 0 2 9
--------------------------------------------------
8122 20 10 0 0 10
--------------------------------------------------
8901 8 0 8 0 0
8901 3 0 0 1 2
Confirmed = Ordered - Cut01 - Cut02 - Cut03
正如您在结果表中看到的,每个代码的Ordered
的总和=从第一个表中为此代码订购,它也适用于Confirmed
的总和。
但是在每一行中我只有一个Cut
不等于0。
我怎么能用T-SQL做到这一点?
答案 0 :(得分:3)
SELECT
Code,
CASE WHEN sub_row = 1 THEN cut01
WHEN sub_row = 2 THEN cut02
WHEN sub_row = 3 THEN ordered - cut01 - cut02 END Ordered,
CASE WHEN sub_row = 1 THEN cut01 ELSE 0 END cut01,
CASE WHEN sub_row = 2 THEN cut02 ELSE 0 END cut02,
CASE WHEN sub_row = 3 THEN cut03 ELSE 0 END cut03,
CASE WHEN sub_row = 3 THEN confirmed ELSE 0 END confirmed
FROM
yourTable
CROSS JOIN
( SELECT 1 AS sub_row
UNION ALL SELECT 2 AS sub_row
UNION ALL SELECT 3 AS sub_row ) AS multiplier_table
WHERE
(sub_row = 1 AND cut01 > 0)
OR (sub_row = 2 AND cut02 > 0)
OR (sub_row = 3 AND cut03 > 0)
OR (sub_row = 3 AND cut01 = 0 AND cut02 = 0 AND cut03 = 0)
答案 1 :(得分:2)
我看到你已经有了你的解决方案,但我只是觉得自从我写完之后我会添加另一个版本: - )
SELECT Code,
conf + Cut01 + Cut02 + Cut03 AS Ordered,
Cut01, Cut02, Cut03, conf AS Confirmed
FROM
(
SELECT Code, Cut01, 0 AS Cut02, 0 AS Cut03,
CASE WHEN Cut01<>0 AND Cut02=0 AND Cut03=0
THEN Confirmed ELSE 0 END conf FROM MyTable
UNION SELECT Code, 0 AS Cut01, Cut02, 0 AS Cut03,
CASE WHEN Cut02<>0 AND Cut03=0
THEN Confirmed ELSE 0 END conf FROM MyTable
UNION SELECT Code, 0 AS Cut01, 0 AS Cut02, Cut03,
CASE WHEN Cut03<>0 OR Cut01=0 AND Cut02=0 AND Cut03=0
THEN Confirmed ELSE 0 END conf FROM MyTable
) a
WHERE conf + Cut01 + Cut02 + Cut03<>0 ORDER BY Code
答案 2 :(得分:1)
从这里开始:
declare @Table as Table ( Number Int )
insert into @Table ( Number ) values ( 2 ), ( 5 )
; with Numbers as (
select 1 as Number
union all
select Number + 1
from Numbers
where Number < 100
)
select *
from @Table as T inner join
Numbers as N on N.Number <= T.Number
硬编码的100
可以替换为所需的最大行数。
答案 3 :(得分:1)
以下是另一种方法:
DECLARE @t TABLE (Code INT, Ordered INT, Cut01 INT,
Cut02 INT, Cut03 INT, Confirmed INT)
INSERT @t
VALUES
(8832,10, 1, 1, 3, 5)
,(8821,12, 0, 1, 2, 9)
,(8122,20, 10, 0, 0, 10)
,(8901,11, 0, 8, 1, 2)
,(1000,2, 0, 0, 0, 2)
;WITH x AS (
SELECT a.Code,
CASE WHEN ColName = 'Cut01' THEN u.Value ELSE 0 END Cut01,
CASE WHEN ColName = 'Cut02' THEN u.Value ELSE 0 END Cut02,
CASE WHEN ColName = 'Cut03' THEN u.Value ELSE 0 END Cut03
FROM @t a
JOIN (
SELECT Value,
ColName,
Code
FROM @t
UNPIVOT
(Value FOR ColName IN (Cut01, Cut02, Cut03)) unpvt
) u ON u.Code = a.Code
), y AS
(
SELECT *,
ROW_NUMBER() OVER
(PARTITION BY Code ORDER BY Cut01 , Cut02 , Cut03)
AS LastRowForCode
FROM x
WHERE Cut01 <> 0 OR Cut02 <> 0 OR Cut03 <> 0
), z AS
(
SELECT COALESCE(y.Code, b.Code) Code,
COALESCE(y.Cut01, b.Cut01) Cut01,
COALESCE(y.Cut02, b.Cut02) Cut02,
COALESCE(y.Cut03, b.Cut03) Cut03,
CASE WHEN Confirmed IS NULL THEN 0 ELSE Confirmed END
AS Confirmed
FROM y
FULL JOIN
@t b ON
b.Code = y.Code
AND y.LastRowForCode = 1
)
SELECT Code,
Confirmed + Cut01 + Cut02 + Cut03 Ordered,
Cut01,
Cut02,
Cut03,
Confirmed
FROM z
ORDER BY Code DESC, Cut01 DESC , Cut02 DESC, Cut03 DESC