3

シンプルなテーブル「TABLE_1」があります

Org   Customer   Code   Ordered   Deleted   Confirmed

RU     Cust_1      A      1000       800        200 
RU     Cust_2      B      300        0          300
US     Cust_3      C      800        100        700
RU     Cust_4      B      100        100        0
US     Cust_5      C      400        200        200 
RU     Cust_6      B      500        300        200   

ここで、「削除済み」<>0 のような行について、このテーブルを変換する必要があります。

Org   Code    Customers          Ordered   Confirmed 

RU     A      Cust_1               1000       200
RU     B      Cust_4, Cust_6       600        200
US     C      Cust_3, Cust_5       1200       900

次のクエリと関数を使用しています

SELECT T1.Org,
       T1.Code,
       dbo.FUNC(T1.Code, T1.Org) AS 'Customers',
       'Ordered' = (SELECT SUM(Ordered) FROM TABLE_1 AS T2 WHERE T2.Customer = T1.Customer AND T2.Code = T1.Code AND T2.Deleted<>0),
       'Confirmed' = (SELECT SUM(Confirmed) FROM TABLE_1 AS T3 WHERE T3.Customer = T1.Customer AND T3.Code = T1.Code AND T3.Deleted<>0)
FROM TABLE_1 AS T1 
WHERE T1.Deleted <> 0

関数「FUNC」:

ALTER FUNCTION [dbo].[FUNC] (@c VARCHAR(MAX), @org VARCHAR(MAX))
RETURNS VARCHAR(MAX) AS BEGIN
DECLARE @p VARCHAR(MAX) ;
SET @p = '' ;
SELECT @p = @p + T1.Customer + ', '
FROM TABLE_1 AS T1
WHERE T1.Code = @c AND T1.Org = @org AND T1.Deleted <> 0
GROUP BY T1.Customer
RETURN SUBSTRING(@p, 1, LEN(@p) - 1)
END

特に大きなテーブルがある場合、これは結果を得る最良の方法ではないと思います。この目的のためのより良い解決策はありますか?

編集: テーブル DDL の例

CREATE TABLE [dbo].[TABLE_1](
[Org] [nchar](10) NULL,
[Customer] [nchar](100) NULL,
[Code] [nchar](10) NULL,
[Ordered] [decimal](18,1) NULL,
[Deleted] [decimal](18,1) NULL,
[Confirmed] [decimal](18,1) NULL) 
ON [PRIMARY]
4

4 に答える 4

1

顧客名に XML 制御文字が含まれている場合でも、これを行うことができます。

ここでフィドル

SELECT
            t1.[Org],
            t1.[Code],
            STUFF(
                (
                 SELECT
                               ', ' + c.[Customer]
                     FROM
                               [TABLE_1] c
                     WHERE
                               c.[Deleted] <> 0
                         AND
                               c.[Org] = t1.[Org]
                         AND
                               c.[Code] = t1.[Code]
                     ORDER BY
                               c.[Customer]
                     FOR XML PATH (''), TYPE
                 ).value('.', 'varchar(max)'),
                 1,
                 2,
                 '') [Customers],
            SUM(t1.[Ordered]),
            SUM(t1.[Confirmed])
    FROM
            [TABLE_1] t1

    WHERE
            t1.[Deleted] <> 0
    GROUP BY
            t1.[Org],
            t1.[Code];

パフォーマンスの観点からは、2 つのクエリを実行するだけで、後でカンマ区切りのリストとして表示することを心配することは理にかなっています。同じ情報が得られますが、MSSQL では実現できない文字列集約のオーバーヘッドはありません。

ここでフィドル

SELECT
            t1.[Org],
            t1.[Code],
            SUM(t1.[Ordered]),
            SUM(t1.[Confirmed])
    FROM
            [TABLE_1] t1

    WHERE
            t1.[Deleted] <> 0
    GROUP BY
            t1.[Org],
            t1.[Code];

SELECT
            t1.[Org],
            t1.[Code],
            t1.[Customer]
    FROM
            [TABLE_1] t1

    WHERE
            t1.[Deleted] <> 0
    ORDER BY
            t1.[Org],
            t1.[Code],
            t1.[Customer];
于 2013-05-08T09:07:00.957 に答える
1

特定のデータでいくつかのテストが必要になる場合がありますが、最初に元のクエリを修正して、質問に書いた正しい結果を期待どおりに取得しましょう。

SELECT T1.Org,
       T1.Code,
       dbo.FUNC(T1.Code, T1.Org) AS Customers,
       SUM(Ordered) AS Ordered,
       SUM(Confirmed) AS Confirmed
FROM TABLE_1 AS T1 
WHERE T1.Deleted <> 0
GROUP BY T1.Org, T1.Code
于 2013-05-08T08:56:39.373 に答える
1

SQLFiddle デモ

SELECT
   Org,
   Code,
   STUFF(
      (SELECT ','+Customer
       FROM t WHERE Code=a.Code and Deleted<>0
       FOR XML PATH('')) , 1 , 1 , '' ),
   SUM(ordered),
   SUM(Confirmed) 

FROM 
   t A 
where Deleted<>0
group by ORG,code
于 2013-05-08T08:53:31.723 に答える