【问题标题】:NTILE Function and Using Inner Join in OracleNTILE函数及Oracle内连接的使用
【发布时间】:2017-09-19 11:22:30
【问题描述】:

我应该使用给定的数据库(它非常大,所以我使用了代码共享)来列出每个分支机构前 5% 客户的姓氏和客户编号。为了找到前 5% 的客户,我决定使用 NTILE 函数(100/5 = 20,因此 NTILE 20)。这些列是从两个单独的表中提取的,所以我使用了内连接。对于我的生活,老实说,我无法弄清楚我哪里出错了。我不断收到“缺少表达”错误,但不知道我到底错过了什么。这是数据库

数据库:https://codeshare.io/5XKKBj ERD:https://drive.google.com/file/d/0Bzum6VJXi9lUX1d2ZkhudTE3QXc/view?usp=sharing

这是我目前的 SQL 查询。

SELECT
  Ntile(20) over
    (partition by Employee.Branch_no
     order by sum(ORDERS.SUBTOTAL) desc
    ) As Top_5,
  CUSTOMER.CUSTOMER_NO,
  CUSTOMER.LNAME
FROM
  CUSTOMER
INNER JOIN ORDERS
  ON
  CUSTOMER.CUSTOMER_NO = ORDERS.CUSTOMER_NO
GROUP BY
  ORDERS.SUBTOTAL,
  CUSTOMER.CUSTOMER_NO,
  CUSTOMER.LNAME;

【问题讨论】:

  • (1) 您缺少Employee 表; (2) GROUP BY 必须在SELECT 子句中包含所有非聚合表达式(即您正在聚合ORDERS.SUBTOTAL,因此您不能在GROUP BY 中包含它); (3) 在应用NTILE之前考虑使用子查询来整理源数据。
  • 不会使用 Employee.Branch_no 等同于实际上有一张桌子吗?我唯一能想到的是使用另一个内部连接,但似乎很浪费。你能解释一下子查询吗?
  • 您不能引用未连接的表。这就是连接的用途。

标签: sql oracle percentile


【解决方案1】:

您需要加入Employee 并且GROUP BY 必须包含所有非聚合表达式。您可以使用子查询生成小计并在外部查询中获取NTILE,例如:

SELECT
  Ntile(20) over
    (partition by BRANCH_NO
     order by sum_subtotal desc
    ) As Top_5,
  CUSTOMER_NO,
  LNAME
FROM (
  SELECT
    EMPLOYEE.BRANCH_NO,
    CUSTOMER.CUSTOMER_NO,
    CUSTOMER.LNAME,
    sum(ORDERS.SUBTOTAL) as sum_subtotal
  FROM CUSTOMER
  JOIN ORDERS
    ON CUSTOMER.CUSTOMER_NO = ORDERS.CUSTOMER_NO
  JOIN EMPLOYEE
    ON ORDERS.EMPLOYEE_NO = EMPLOYEE.EMPLOYEE_NO
  GROUP BY
    EMPLOYEE.BRANCH_NO,
    CUSTOMER.CUSTOMER_NO,
    CUSTOMER.LNAME
  );

注意:您可能还希望在选择列表中包含 BRANCH_NO,否则输出会与重复的客户混淆(如果客户从多个分支机构的员工那里订购)。

现在,如果您想过滤上述查询以仅获得前 5%,您可以将整个内容放在另一个子查询中,并在 Top_5 列上添加谓词,例如:

SELECT CUSTOMER_NO, LNAME
FROM (... the query above...)
WHERE Top_5 = 1;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-19
    • 2018-07-31
    • 2014-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多