【问题标题】:Syntax problem with aggregate functions and subqueries聚合函数和子查询的语法问题
【发布时间】:2019-11-08 10:21:19
【问题描述】:

我正在尝试查询一个包含 3 个表的数据库 Orders、customer 和 salesperson。 为了找到更多关于销售人员近期表现的信息。想要的类别是 id、年龄、数量 > 1000 的订单数量、数量 > 500 (y/n) 的订单、服务的唯一客户数量、自上次订购以来的天数以及最后一次订购的金额。

我的代码如下,也可以在链接中查看:

SELECT  o.salesperson_id
    s.Age,
    (CASE WHEN o.Amount > 500 THEN 'Yes' ELSE 'No' END) AS 'Had Order Bigger Than 500?',
    (datediff(day,o.order_date,GETDATE())) AS 'Days Since Last Order',

    o.Amount as 'Last Order Amount'
    FROM Orders o INNER JOIN Salesperson s ON o.salesperson_id = s.ID
      WHERE o.Amount IN
      (SELECT o.Amount WHERE o.order_date = MAX (o.order_date) FROM Orders)

    GROUP BY o.salesperson_id 
    HAVING (COUNT (DISTINCT o.cust_id)) AS 'Number of Unique Customers Served',
    (SUM(CASE WHEN o.Amount > 1000 THEN 1 ELSE 0 END)) AS 'Number of Orders Bigger Than 1000'

    ORDER BY o.salesperson_id;

http://sqlfiddle.com/#!18/4fc5c/69

自动调试器说问题出在我的 FROM 上,但我很笨

关键字“FROM”附近的语法不正确

我的预期结果是这样的:

+----------------+-----------------+-----------------------------------+-----------------------------------+-----------------------------------+-----------------------+-------------------+
| Salesperson ID | Salesperson Age | Number of Orders Bigger Than 1000 | Had Order Bigger Than 500? (y/n)  | Number of Unique Customers Served | Days Since Last Order | Last Order Amount |
+----------------+-----------------+-----------------------------------+-----------------------------------+-----------------------------------+-----------------------+-------------------+
|              1 |              61 |                                 0 | N                                 |                                 1 |                       |               460 |
|              2 |              34 |                                 1 | Y                                 |                                 2 |                       |              2400 |
|              8 |              57 |                                 1 | y                                 |                                 1 |                       |              1800 |
+----------------+-----------------+-----------------------------------+-----------------------------------+-----------------------------------+-----------------------+-------------------+

非常感谢收到的所有帮助。

【问题讨论】:

  • sqlfiddle 很不错,而且还在这里添加了示例表数据和预期结果,以及查询尝试。 (作为格式化文本,没有图像。)
  • WHEREFROM 之后
  • WHERE 子句中的子查询中的表需要别名。那就是 FROM 不好。
  • @HoneyBadger 所说的。而您在“WHERE o.Amount in”之后的子查询是指您的 Orders 表的主表别名 (o),而不是您在子查询中使用的副本
  • 查询需要检查"Where" 子句在"From" 子句之后的位置。您也不能在"Where" 子句中直接使用聚合函数。必须使用 "Having" 子句。

标签: sql sql-server aggregate


【解决方案1】:

加入销售人员和订单,按销售人员分组并使用条件聚合:

select
  s.ID [Salesperson ID], 
  s.Age [Salesperson Age],
  sum(case when o.Amount > 1000 then 1 else 0 end) [Number of Orders Bigger Than 1000],
  case when sum(case when o.Amount > 500 then 1 else 0 end) > 0 then 'Yes' else 'No' end [Had Order Bigger Than 500? (y/n)],
  count(distinct cust_id) [Number of Unique Customers Served],
  datediff(day, max(o.order_date), GETDATE()) [Days Since Last Order],
  (select Amount from Orders where salesperson_id = s.ID and order_date = max(o.order_date))[Last Order Amount]
from Salesperson s inner join Orders o
on o.salesperson_id = s.ID
group by s.ID, s.Age
order by s.ID

请参阅demo
结果:

> Salesperson ID | Salesperson Age | Number of Orders Bigger Than 1000 | Had Order Bigger Than 500? (y/n) | Number of Unique Customers Served | Days Since Last Order | Last Order Amount
> -------------: | --------------: | --------------------------------: | :------------------------------- | --------------------------------: | --------------------: | ----------------:
>              1 |              61 |                                 0 | No                               |                                 1 |                  8883 |               460
>              2 |              34 |                                 1 | Yes                              |                                 2 |                  7953 |              2400
>              8 |              57 |                                 1 | Yes                              |                                 1 |                  7587 |              1800

【讨论】:

    【解决方案2】:

    您的查询syntax 完全错误。请试试这个。

    FIDDLE DEMO

    SELECT  o.salesperson_id, s.Age,
         (SUM(CASE WHEN o.Amount > 1000 THEN 1 ELSE 0 END)) AS 'Number of Orders Bigger Than 1000',
         (CASE WHEN o.Amount > 500 THEN 'Yes' ELSE 'No' END) AS 'Had Order Bigger Than 500?',
         (COUNT (o.cust_id)) AS 'Number of Unique Customers Served',
         (datediff(day,o.order_date,GETDATE())) AS 'Days Since Last Order',
         o.Amount as 'Last Order Amount'  
    FROM Orders o INNER JOIN Salesperson s ON o.salesperson_id = s.ID
    WHERE o.Amount IN
    ( 
      SELECT Amount 
      FROM Orders OO
      WHERE order_date IN (SELECT MAX(order_date) FROM Orders GROUP BY salesperson_id)
    )
    GROUP BY o.salesperson_id,s.Age,o.Amount, (datediff(day,o.order_date,GETDATE()))
    ORDER BY o.salesperson_id;
    

    【讨论】:

    • 谢谢!因此,为了学习目的,重申一下 - 我的原始代码中的主要错误如下: 1. 不正确地将 () 用于案例和聚合函数 2. 错误的 WHERE 和 FROM 顺序 3. 在子查询中重复和重复调用金额。我还不清楚两件事 - 当我需要使用 HAVING 时,你显然没有在这里。其次,你不能在没有别名的情况下对同一个表进行子查询吗?
    • 你可以在 select 子句中使用聚合函数,如果你想在 where 子句中使用它,那么你可能需要在 where 子句中没有使用 having 子句
    • [Number of Unique Customers Served] 的结果错误。
    猜你喜欢
    • 1970-01-01
    • 2011-04-08
    • 1970-01-01
    • 1970-01-01
    • 2011-09-27
    • 2021-09-10
    • 1970-01-01
    • 1970-01-01
    • 2011-07-26
    相关资源
    最近更新 更多