2

を使用してうまく機能する、私が書いたクエリがありますWITH ROLLUP。幅は 6 列で、最後の列には注文金額を表す数字が含まれます。他の 5 つの列のそれぞれは、列 5 が注文番号で、その注文を識別する際により具体的になります。

クエリは、関心のある組織の特定の「レベル」のすべての合計を表示します。ただし、レポートから重複データを削除する必要があります。重複する行はありませんが、より一般的な各列には、連続する行に多数の繰り返しデータがあります。

クエリは正常に動作し、次のような結果が生成されます。

+-----------------------------------------------------------------------------------------------+
¦ Affiliate Company ¦ Affiliate Name ¦ Customer Company ¦ Customer ¦ Order Number ¦ Total Sales ¦
¦-------------------+----------------+------------------+----------+--------------+-------------¦
¦ OL                ¦ Brian          ¦ Customer         ¦ Dennis   ¦ 105773       ¦ $111.60     ¦
¦ OL                ¦ Brian          ¦ Customer         ¦ Steve    ¦ 105776       ¦ $398.75     ¦
¦ OL                ¦ Brian          ¦ Customer         ¦ NULL     ¦ subtotal     ¦ $510.35     ¦
¦ OL                ¦ Brian          ¦ NULL             ¦ NULL     ¦ subtotal     ¦ $510.35     ¦
¦ OL                ¦ NULL           ¦ NULL             ¦ NULL     ¦ subtotal     ¦ $510.35     ¦
¦ ght               ¦ Tom            ¦ Customer         ¦ John     ¦ 104686       ¦ $1,228.10   ¦
¦ ght               ¦ Tom            ¦ Customer         ¦ Julie    ¦ 105701       ¦ $152.64     ¦
¦ ght               ¦ Tom            ¦ Customer         ¦ Jennifer ¦ 104681       ¦ $5.00       ¦
¦ ght               ¦ Tom            ¦ Customer         ¦ Jennifer ¦ 105766       ¦ $218.79     ¦
¦ ght               ¦ Tom            ¦ Customer         ¦ Jason    ¦ 104684       ¦ $2,500.00   ¦
¦ ght               ¦ Tom            ¦ Customer         ¦ Jason    ¦ 104691       ¦ $321.28     ¦
¦ ght               ¦ Tom            ¦ Customer         ¦ Jason    ¦ 105744       ¦ $739.80     ¦
¦ ght               ¦ Tom            ¦ Customer         ¦ Jean     ¦ 104682       ¦ $3,990.00   ¦
¦ ght               ¦ Tom            ¦ Customer         ¦ Random   ¦ 104688       ¦ $1,328.40   ¦
¦ ght               ¦ Tom            ¦ Customer         ¦ Random   ¦ 105699       ¦ $5,112.00   ¦
¦ ght               ¦ Tom            ¦ Customer         ¦ Random   ¦ 105711       ¦ $219.10     ¦
¦ ght               ¦ Tom            ¦ Customer         ¦ Random   ¦ 105758       ¦ $2,202.50   ¦
¦ ght               ¦ Tom            ¦ Customer         ¦ Jason    ¦ 105739       ¦ $2,278.04   ¦
¦ ght               ¦ Tom            ¦ Customer         ¦ Jason    ¦ 105769       ¦ $820.84     ¦
¦ ght               ¦ Tom            ¦ Customer         ¦ Jason    ¦ 105770       ¦ $797.12     ¦
¦ ght               ¦ Tom            ¦ Customer         ¦ Dee Dee  ¦ 105702       ¦ $2,244.30   ¦
¦ ght               ¦ Tom            ¦ Customer         ¦ NULL     ¦ subtotal     ¦ $24,157.91  ¦
¦ ght               ¦ Tom            ¦ NULL             ¦ NULL     ¦ subtotal     ¦ $24,157.91  ¦
¦ ght               ¦ NULL           ¦ NULL             ¦ NULL     ¦ subtotal     ¦ $24,157.91  ¦
¦ NULL              ¦ NULL           ¦ NULL             ¦ NULL     ¦ subtotal     ¦ $24,668.26  ¦
+-----------------------------------------------------------------------------------------------+

ただし、LAG をミックスに追加して重複データを削除すると、次のようになります。

+----------------------------------------------------------------------------------------------------------+
¦ Affiliate Company ¦ Affiliate Name ¦ Customer Company ¦ Customer ¦ Order Number ¦ Total Sales ¦ Previous ¦
¦-------------------+----------------+------------------+----------+--------------+-------------+----------¦
¦ NULL              ¦ NULL           ¦ NULL             ¦ NULL     ¦ subtotal     ¦ $24,668.26  ¦ NULL     ¦
¦ OL                ¦ NULL           ¦ NULL             ¦ NULL     ¦ subtotal     ¦ $510.35     ¦ NULL     ¦
¦ OL                ¦ Brian          ¦ NULL             ¦ NULL     ¦ subtotal     ¦ $510.35     ¦ NULL     ¦
¦ OL                ¦ Brian          ¦ Customer         ¦ NULL     ¦ subtotal     ¦ $510.35     ¦ NULL     ¦
¦ OL                ¦ Brian          ¦ Customer         ¦ Dennis   ¦ 105773       ¦ $111.60     ¦ NULL     ¦
¦ OL                ¦ Brian          ¦ Customer         ¦ Steve    ¦ 105776       ¦ $398.75     ¦ Dennis   ¦
¦ ght               ¦ NULL           ¦ NULL             ¦ NULL     ¦ subtotal     ¦ $24,157.91  ¦ Steve    ¦
¦ ght               ¦ Tom            ¦ NULL             ¦ NULL     ¦ subtotal     ¦ $24,157.91  ¦ NULL     ¦
¦ ght               ¦ Tom            ¦ Customer         ¦ NULL     ¦ subtotal     ¦ $24,157.91  ¦ NULL     ¦
¦ ght               ¦ Tom            ¦ Customer         ¦ John     ¦ 104686       ¦ $1,228.10   ¦ NULL     ¦
¦ ght               ¦ Tom            ¦ Customer         ¦ Julie    ¦ 105701       ¦ $152.64     ¦ John     ¦
¦ ght               ¦ Tom            ¦ Customer         ¦ Jennifer ¦ 104681       ¦ $5.00       ¦ Julie    ¦
¦ ght               ¦ Tom            ¦ Customer         ¦ Jennifer ¦ 105766       ¦ $218.79     ¦ Jennifer ¦
¦ ght               ¦ Tom            ¦ Customer         ¦ Jason    ¦ 104684       ¦ $2,500.00   ¦ Jennifer ¦
¦ ght               ¦ Tom            ¦ Customer         ¦ Jason    ¦ 104691       ¦ $321.28     ¦ Jason    ¦
¦ ght               ¦ Tom            ¦ Customer         ¦ Jason    ¦ 105744       ¦ $739.80     ¦ Jason    ¦
¦ ght               ¦ Tom            ¦ Customer         ¦ Jean     ¦ 104682       ¦ $3,990.00   ¦ Jason    ¦
¦ ght               ¦ Tom            ¦ Customer         ¦ Random   ¦ 104688       ¦ $1,328.40   ¦ Jean     ¦
¦ ght               ¦ Tom            ¦ Customer         ¦ Random   ¦ 105699       ¦ $5,112.00   ¦ Random   ¦
¦ ght               ¦ Tom            ¦ Customer         ¦ Random   ¦ 105711       ¦ $219.10     ¦ Random   ¦
¦ ght               ¦ Tom            ¦ Customer         ¦ Random   ¦ 105758       ¦ $2,202.50   ¦ Random   ¦
¦ ght               ¦ Tom            ¦ Customer         ¦ Jason    ¦ 105739       ¦ $2,278.04   ¦ Random   ¦
¦ ght               ¦ Tom            ¦ Customer         ¦ Jason    ¦ 105769       ¦ $820.84     ¦ Jason    ¦
¦ ght               ¦ Tom            ¦ Customer         ¦ Jason    ¦ 105770       ¦ $797.12     ¦ Jason    ¦
¦ ght               ¦ Tom            ¦ Customer         ¦ Dee Dee  ¦ 105702       ¦ $2,244.30   ¦ Jason    ¦
+----------------------------------------------------------------------------------------------------------+

「前」列を追加しただけで、データが逆になっていることがわかります。私の意図は、戻って、連続する重複をすべて除外することです。ただし、このようにデータを逆向きにすると、重複を効果的に削除することも、結果を簡単に読み取ることもできません。私がやりたいことを達成する方法について何か考えはありますか?

私のコードは次のとおりです。

更新:ソートの助けを借りて、次のコードですべてがうまくいきました:

WITH Names AS (
SELECT 
Customer.CustomerID
, Customer.LastName + ', ' + Customer.FirstName + ' (' + Customer.Email + ')' AS 'Customer'
FROM
Customer
)
SELECT
CASE WHEN (Affiliate.Company = LAG(Affiliate.Company, 1) OVER (ORDER BY Affiliate.Company) AND GROUPING(Affiliate.Name) < 1) THEN NULL ELSE CASE WHEN GROUPING(Affiliate.Name) < 1 THEN Affiliate.Company ELSE Affiliate.Company + ' subtotal:' END END AS 'Affiliate Company'
, CASE WHEN (Affiliate.Name = LAG(Affiliate.Name, 1) OVER (ORDER BY Affiliate.Company, Affiliate.Name) AND GROUPING(CustomerLevel.Name) < 1) THEN NULL ELSE CASE WHEN GROUPING(CustomerLevel.Name) < 1 THEN Affiliate.Name ELSE Affiliate.Name + ' subtotal:' END END AS 'Affiliate Name'
, CASE WHEN (CustomerLevel.Name = LAG(CustomerLevel.Name, 1) OVER (ORDER BY Affiliate.Company, Affiliate.Name, CustomerLevel.Name) AND GROUPING(Names.Customer) < 1) THEN NULL ELSE CASE WHEN GROUPING(Names.Customer) < 1 THEN CustomerLevel.Name ELSE CustomerLevel.Name + ' subtotal:' END END AS 'Customer Company'
, Names.Customer AS 'Customer'
, CASE GROUPING(Orders.OrderNumber) WHEN 1 THEN CASE WHEN GROUPING(Affiliate.Company) = 1 THEN 'GRAND TOTAL' ELSE 'subtotal' END ELSE CONVERT(VARCHAR,Orders.OrderNumber) END AS 'Order Number'
, '$' + CONVERT(VARCHAR,CONVERT(MONEY,SUM(Orders.OrderSubtotal)),1) AS 'Total Sales'
FROM            Orders INNER JOIN
                         Affiliate ON Orders.AffiliateID = Affiliate.AffiliateID INNER JOIN
                         Customer ON Orders.CustomerID = Customer.CustomerID INNER JOIN
                         CustomerLevel ON Customer.CustomerLevelID = CustomerLevel.CustomerLevelID INNER JOIN
                         Names ON Customer.CustomerID = Names.CustomerID
GROUP BY
Affiliate.Company
, Affiliate.Name
, CustomerLevel.Name
, Names.Customer
, Orders.OrderNumber
WITH ROLLUP
HAVING
GROUPING(Orders.OrderNumber) < 1
OR
GROUPING(Names.Customer) = 1
OR
GROUPING(Affiliate.Company) = 1
OR
GROUPING(Affiliate.Name) = 1
OR
GROUPING(CustomerLevel.Name) = 1
ORDER BY
CASE WHEN Affiliate.Company IS NULL THEN 1 ELSE 0 END
, Affiliate.Company
, CASE WHEN Affiliate.Name IS NULL THEN 1 ELSE 0 END
, Affiliate.Name
, CASE WHEN CustomerLevel.Name IS NULL THEN 1 ELSE 0 END
, CustomerLevel.Name
, CASE WHEN Names.Customer IS NULL THEN 1 ELSE 0 END
, Names.Customer

更新:誰かが興味を持っている場合に備えて、不要な連続した重複をすべて削除した結果を次に示します。

+-------------------+-----------------+--------------------+----------+--------------+-------------+
| Affiliate Company | Affiliate Name  |  Customer Company  | Customer | Order Number | Total Sales |
+-------------------+-----------------+--------------------+----------+--------------+-------------+
| OL                | Brian           | Customer           | Dennis   | 105773       | $111.60     |
| NULL              | NULL            | NULL               | Steve    | 105776       | $398.75     |
| NULL              | NULL            | Customer subtotal: | NULL     | subtotal     | $510.35     |
| NULL              | Brian subtotal: | NULL               | NULL     | subtotal     | $510.35     |
| WYN-OL subtotal:  | NULL            | NULL               | NULL     | subtotal     | $510.35     |
| ght               | Tom             | Customer           | John     | 104686       | $1,228.10   |
| NULL              | NULL            | NULL               | Julie    | 105701       | $152.64     |
| NULL              | NULL            | NULL               | Jennifer | 104681       | $5.00       |
| NULL              | NULL            | NULL               | Jennifer | 105766       | $218.79     |
| NULL              | NULL            | NULL               | Jason    | 104684       | $2,500.00   |
| NULL              | NULL            | NULL               | Jason    | 104691       | $321.28     |
| NULL              | NULL            | NULL               | Jason    | 105744       | $739.80     |
| NULL              | NULL            | NULL               | Jean     | 104682       | $3,990.00   |
| NULL              | NULL            | NULL               | Random   | 104688       | $1,328.40   |
| NULL              | NULL            | NULL               | Random   | 105699       | $5,112.00   |
| NULL              | NULL            | NULL               | Random   | 105711       | $219.10     |
| NULL              | NULL            | NULL               | Random   | 105758       | $2,202.50   |
| NULL              | NULL            | NULL               | Jason    | 105739       | $2,278.04   |
| NULL              | NULL            | NULL               | Jason    | 105769       | $820.84     |
| NULL              | NULL            | NULL               | Jason    | 105770       | $797.12     |
| NULL              | NULL            | NULL               | Dee Dee  | 105702       | $2,244.30   |
| NULL              | NULL            | Customer subtotal: | NULL     | subtotal     | $24,157.91  |
| NULL              | Tom subtotal:   | NULL               | NULL     | subtotal     | $24,157.91  |
| ght subtotal:     | NULL            | NULL               | NULL     | subtotal     | $24,157.91  |
| NULL              | NULL            | NULL               | NULL     | GRAND TOTAL  | $24,668.26  |
+-------------------+-----------------+--------------------+----------+--------------+-------------+

このようなことは、多くの場合、SQL 以外の言語で行うのが最適であることを私は知っています。ただし、プロジェクトのこの時点では、これはオプションではありません。私はSQLでそれを行うか、「余分な」データを処理する必要があります。

*表の書式設定ツールについてhttp://www.sensefulsolutions.com/2010/10/format-text-as-table.htmlを称賛してください!

4

2 に答える 2

1

ORDER BY他の誰もが既に述べたように、最も外側の節を使用して必要な出力順序を指定しない限り、SQL Server (またはその他の RDBMS) は出力順序を保証しませんSELECT。noORDER BYが指定されている場合、実行計画の変更によって出力順序が変更される可能性があります。クエリの実行時に使用可能な (= ビジーではない) プロセッサの数でさえ、出力順序に影響を与える可能性があります。

GROUP BYエンジンがデータをソートする必要はありません。データ セットが十分に大きい場合、SQL Server は Stream-Aggregate の代わりに Hash-Aggregate を使用します。その場合、行はランダムな順序で返されます。繰り返しますが、特定の順序で行が必要な場合は、 で指定する必要がありますORDER BY

関数の結果はLAG()、最終的な行の順序とは無関係です。OVER()独自の句で指定された順序によってのみ影響を受けます。LAG異なる順序を使用して複数の を使用することもできます。

つまり、現在の行の値とLAGed の値の間で行う必要のある比較はすべて正しく行われます。

于 2013-04-12T21:53:34.723 に答える
0

これはうまくいくはずです:

WITH Names AS (
SELECT 
Customer.CustomerID
, Customer.LastName + ', ' + Customer.FirstName + ' (' + Customer.Email + ')' AS 'Customer'
FROM
Customer
)
SELECT
Affiliate.Company AS 'Affiliate Company'
, Affiliate.Name AS 'Affiliate Name'
, CustomerLevel.Name AS 'Customer Company'
, Names.Customer as 'Customer'
, CASE GROUPING(Orders.OrderNumber) WHEN 1 THEN 'subtotal' ELSE CONVERT(VARCHAR,Orders.OrderNumber) END AS 'Order Number'
, '$' + CONVERT(VARCHAR,CONVERT(MONEY,SUM(Orders.OrderSubtotal)),1) AS 'Total Sales'
, LAG(Names.Customer, 1) OVER (ORDER BY Affiliate.Company, Affiliate.Name, CustomerLevel.Name, Names.Customer) AS 'Previous'
FROM            Orders INNER JOIN
                         Affiliate ON Orders.AffiliateID = Affiliate.AffiliateID INNER JOIN
                         Customer ON Orders.CustomerID = Customer.CustomerID INNER JOIN
                         CustomerLevel ON Customer.CustomerLevelID = CustomerLevel.CustomerLevelID INNER JOIN
                         Names ON Customer.CustomerID = Names.CustomerID
GROUP BY
Affiliate.Company
, Affiliate.Name
, CustomerLevel.Name
, Names.Customer
, Orders.OrderNumber
WITH ROLLUP
HAVING
GROUPING(Orders.OrderNumber) < 1
OR
GROUPING(Names.Customer) = 1
OR
GROUPING(Affiliate.Company) = 1
OR
GROUPING(Affiliate.Name) = 1
OR
GROUPING(CustomerLevel.Name) = 1
ORDER BY     
    GROUPING(Affiliate.Company),
    GROUPING(Affiliate.Name),
    GROUPING(CustomerLevel.Name),
    GROUPING(Names.Customer)
于 2013-04-12T21:53:26.593 に答える