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    ¦
+----------------------------------------------------------------------------------------------------------+

你可以看到我所做的只是添加了“Previous”列,我的数据现在被反转了。我的意图是我会回去过滤掉所有连续的重复项。但是,像这样反向数据,我无法有效地删除重复项,甚至无法轻松读取结果。关于如何完成我想要做的任何想法?

我的代码如下:

更新:在排序的帮助下,一切都使用以下代码:

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

正如其他人已经说过的那样,SQL Server(或与此相关的任何 RDBMS)不对输出顺序做出任何保证,除非您使用ORDER BY最外层的子句指定所需的输出顺序SELECT。如果ORDER BY指定 no,则执行计划更改可以更改输出顺序。即使是查询执行时可用(= 非忙碌)处理器的数量也会影响输出顺序。

GROUP BY不需要引擎对数据进行排序。如果数据集足够大,SQL Server 将使用 Hash-Aggregate 而不是 Stream-Aggregate。如果发生这种情况,行将按随机顺序返回。同样,如果您需要按特定顺序排列的行,则需要使用ORDER BY.

LAG()函数的结果与最终的行顺序无关。它只受它自己的OVER()子句中指定的顺序的影响。你甚至可以有多个LAGs 使用不同的顺序。

这意味着,您可能想要在当前行的值和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 回答