2

我的 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 来做到这一点?

4

4 回答 4

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)
于 2012-08-09T11:01:23.110 回答
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
于 2012-08-09T15:20:44.863 回答
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可以替换为所需的最大行数。

于 2012-08-09T11:06:43.850 回答
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
于 2012-08-09T11:43:30.803 回答