【问题标题】:Is there a better way to execute this SQL query?有没有更好的方法来执行这个 SQL 查询?
【发布时间】:2021-01-05 11:09:17
【问题描述】:

我编写了这个 SQL 查询来获取数据库中每个客户的数据。

如您所见,我正在尝试获取未付款订单的总数和我的查询的订单总数。

我最后的目标是只获得未付款订单的用户(我想我必须在查询结束时使用HAVING)。

这是我的查询

SELECT 
u.id, 
u.first_name, 
u.last_name, 
u.email, 
u.phone, 
(SELECT COUNT(*) FROM account_order WHERE account_order.user_id = u.id AND account_order.is_paid = False AND account_order.max_meals > 0) as total_not_paid,
(SELECT COUNT(*) FROM account_order WHERE account_order.user_id = u.id) AS total_orders
FROM account_user u

您认为有更好的方法来获取记录吗?

如何获取只有一个total_not_paid 和一个total_order 的用户?

【问题讨论】:

    标签: sql postgresql performance optimization heroku-postgres


    【解决方案1】:

    如果您想要未付款的订单,可以使用显式聚合和having 子句:

    SELECT u.*,
           COUNT(*) FILTER (WHERE NOT is_paid AND ao.max_meals > 0) as total_not_paid,
           COUNT(*) AS total_orders
    FROM account_user u JOIN
         account_order ao
         ON ao.user_id = u.id
    GROUP BY u.id
    HAVING COUNT(*) FILTER (WHERE NOT is_paid AND ao.max_meals > 0) > 0;
    

    【讨论】:

    • 这看起来像我需要的,但我收到错误ERROR: syntax error at or near "NOT" LINE 2: COUNT(*) FILTER (NOT is_paid AND ao.max_meals > 0) as...
    • WHERE 缺失:COUNT(*) FILTER (WHERE NOT is_paid AND ao.max_meals > 0)
    • @FrankHeikens 。 . .谢谢你。我真的不明白为什么需要WHERE,因为FILTER 已经暗示了这一点。
    • @GordonLinoff:我也没有,我已经犯这个错误好几年了,还不能习惯。
    【解决方案2】:

    您可以按如下方式使用条件聚合:

    SELECT u.id, u.first_name,  u.last_name, u.email, u.phone, 
           count(case when ao.is_paid = False AND ao.max_meals > 0 then 1 end) 
             as total_not_paid,
           count(ao.*) AS total_orders
      FROM account_user u
      left join account_order ao on account_order.user_id = u.id
      group by u.id;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多