0

假设我有一个包含以下列的表格:

  • 类型
  • 供应商
  • 命令
  • 全部的

我想查询这些数据,以便得到有序的结果,首先按 TYPE 分组。订单是订单数量。然后以下查询对我来说很有效(http://sqlfiddle.com/#!15/78cc1/1):

WITH company_sales(type, department, supplier, order_number, total) AS (
   VALUES
     ('Edibles'    , 'Department-1', 'Supplier-1' , 'ORDER-1' ,   10)
   , ('Edibles'    , 'Department-1', 'Supplier-2' , 'ORDER-2' ,   20)
   , ('Edibles'    , 'Department-1', 'Supplier-3' , 'ORDER-3' ,   30)
   , ('Edibles'    , 'Department-1', 'Supplier-4' , 'ORDER-4' ,   40)
   , ('Edibles'    , 'Department-2', 'Supplier-5' , 'ORDER-5' ,   50)
   , ('Edibles'    , 'Department-2', 'Supplier-6' , 'ORDER-6' ,   60)
   , ('Edibles'    , 'Department-3', 'Supplier-7' , 'ORDER-7' ,   70)
   , ('Edibles'    , 'Department-3', 'Supplier-8' , 'ORDER-8' ,   80)
   , ('Edibles'    , 'Department-3', 'Supplier-9' , 'ORDER-9' ,   90)
   , ('Edibles'    , 'Department-3', 'Supplier-9' , 'ORDER-10',  100)
   , ('Edibles'    , 'Department-4', 'Supplier-10', 'ORDER-11',  110)
   , ('Non-Edibles', 'Department-2', 'Supplier-11', 'ORDER-12', 1000)
   , ('Non-Edibles', 'Department-3', 'Supplier-12', 'ORDER-13', 1010)
   , ('Non-Edibles', 'Department-3', 'Supplier-13', 'ORDER-14', 1020)
   , ('Non-Edibles', 'Department-3', 'Supplier-14', 'ORDER-15', 1030)
   , ('Non-Edibles', 'Department-3', 'Supplier-14', 'ORDER-16', 1040)
   , ('Non-Edibles', 'Department-4', 'Supplier-15', 'ORDER-17', 1050)
)
SELECT cs.type,
       count(*)   sum_total_count,
       sum(total) sum_grand_total
FROM   company_sales cs
GROUP  BY cs.type
ORDER  BY Sum(Count(*)) OVER (partition BY cs.type) DESC,
          cs.type ASC;

如果我想查询这些数据以获得有序的结果,首先按类型分组,然后按部门分组。订单是订单数量。然后下面的查询对我很有效(http://sqlfiddle.com/#!15/78cc1/2):

WITH company_sales(type, department, supplier, order_number, total) AS ( ...)
SELECT cs.type,
       cs.department,
       count(*)   sum_total_count,
       sum(total) sum_grand_total
FROM   company_sales cs
GROUP  BY cs.type,
          cs.department
ORDER  BY Sum(Count(*)) OVER (partition BY cs.type) DESC,
          Sum(Count(*)) OVER (partition BY cs.type, cs.department) DESC,
          cs.type ASC,
          cs.department ASC;

但是,当我想要订购结果时遵循相同的模式,首先按类型分组,然后按部门分组,然后按供应商分组,顺序是订单数。然后以下查询对我不起作用http://sqlfiddle.com/#!15/78cc1/3):

WITH company_sales(type, department, supplier, order_number, total) AS (...)
SELECT cs.type,
       cs.department,
       cs.supplier,
       count(*)   sum_total_count,
       sum(total) sum_grand_total
FROM   company_sales cs
GROUP  BY cs.type,
          cs.department,
          cs.supplier
ORDER  BY Sum(Count(*)) OVER (partition BY cs.type) DESC,
          Sum(Count(*)) OVER (partition BY cs.type, cs.department) DESC,
          Sum(Count(*)) OVER (partition BY cs.type, cs.department, cs.supplier) DESC,
          cs.type ASC,
          cs.department ASC,
          cs.supplier ASC;

上述查询结果如下:

结果集不正确

鉴于,我希望以下内容:

所需的正确结果集

我哪里错了?

4

1 回答 1

2

两个预科:

  1. 永远不要使用 SQL 保留关键字作为列名。在接下来的type -> typorder -> ordnum
  2. 学会使用VALUES从句。我建议您根据以下示例编辑您的问题,无需重复 3 次(只需使用类似WITH company_sales (...) AS (...) SELECT ...的内容;例如,PG 手册就是这样做的)。事实上,你的问题太冗长了,人们不会通读它。(好的 - Erwin Brandstetter 从 OP 中编辑了这个)

第一的

ORDER BY由于您以错误的顺序指定子句,因此查询返回的结果不是您想要的顺序。在typ = 'Edibles'部门 1 和 3 下都有 4 个订单。分析您的ORDER BY条款,我们看到以下内容:

      -- 1. This orders by the type with the most orders - OK
ORDER BY Sum(Count(*)) OVER (PARTITION BY cs.type) DESC,
      -- 2. Number of orders by department within each type - OK but tie #1 and #3
         Sum(Count(*)) OVER (PARTITION BY cs.type, cs.department) DESC,
      -- 3. Number of orders by supplier with each type, department - NOT OK
         Sum(Count(*)) OVER (PARTITION BY cs.type, cs.department, cs.supplier) DESC,
      -- 4. In case of ties, order by type name - OK
         cs.type ASC,
      -- 5. In case of ties, order by department name - OK
         cs.department ASC,
      -- 6. In case of ties, order by supplier name - OK
         cs.supplier ASC;

那么为什么#3 不行呢?事实上,#3 很好,但#4、#5 和#6 放错了地方。您想按类型数量排序,然后是部门,然后是供应商,并按字母顺序解决关系。您应该在每次对行数进行排序后立即解决这些关系(删除过时的表别名和ASC子句):

ORDER BY
  Sum(Count(*)) OVER (PARTITION BY typ) DESC, typ,
  Sum(Count(*)) OVER (PARTITION BY typ, department) DESC, department,
  Sum(Count(*)) OVER (PARTITION BY typ, department, supplier) DESC, supplier;

那么为什么你的订购错误呢?好吧,“Edibles”中的第 1 和第 3 部门各有 4 行,因此它们是并列的。以下条款向供应商 9 订购 2 个订单,高于其他供应商各 1 个订单。在供应商订单之前按部门名称订购打破了部门之间的联系,并且您的所有行订单都很好。

然后

该条款Sum(Count(*)) OVER (PARTITION BY ...)是胡说八道。count(*)为分区中的每一行分配一个新列,其中包含该分区中的行数。再次将其相加会得到与基本行数具有完全相同排序属性的正方形。

此外,Sum(Count(*)) OVER (PARTITION BY typ, department, supplier)没有用,因为您已经在选择列表GROUP BY中生成了这些相同的列。count(*)

将所有这些放在一起并使用位置参数为简洁起见,我们得到:

WITH company_sales(typ, department, supplier, ordnum, total) AS (...)
SELECT typ,
       department,
       supplier,
       count(*) sum_total_count,
       sum(total) sum_grand_total
FROM   company_sales
GROUP  BY 1, 2, 3
ORDER BY
      count(*) OVER (PARTITION BY typ) DESC, 1,
      count(*) OVER (PARTITION BY typ, department) DESC, 2,
      4 DESC, 3;

导致:

     typ     |  department  |  supplier   | sum_total_count | sum_grand_total
-------------+--------------+-------------+-----------------+-----------------
 Edibles     | Department-1 | Supplier-1  |               1 |              10
 Edibles     | Department-1 | Supplier-2  |               1 |              20
 Edibles     | Department-1 | Supplier-3  |               1 |              30
 Edibles     | Department-1 | Supplier-4  |               1 |              40
 Edibles     | Department-3 | Supplier-9  |               2 |             190
 Edibles     | Department-3 | Supplier-7  |               1 |              70
 Edibles     | Department-3 | Supplier-8  |               1 |              80
 Edibles     | Department-2 | Supplier-5  |               1 |              50
 Edibles     | Department-2 | Supplier-6  |               1 |              60
 Edibles     | Department-4 | Supplier-10 |               1 |             110
 Non-Edibles | Department-3 | Supplier-12 |               1 |            1010
 Non-Edibles | Department-3 | Supplier-13 |               1 |            1020
 Non-Edibles | Department-3 | Supplier-14 |               2 |            2070
 Non-Edibles | Department-2 | Supplier-11 |               1 |            1000
 Non-Edibles | Department-4 | Supplier-15 |               1 |            1050
(15 rows)
于 2016-01-27T04:27:33.043 回答