【问题标题】:How to better optimize SQL queries?如何更好地优化 SQL 查询?
【发布时间】:2018-10-08 23:45:32
【问题描述】:

我写了请求,但我担心它可能非常未优化,我会遇到问题。

任务:查找没有债务且最近一次付款超过 2 年的用户。没有任何订单的不必要用户

我们有两张桌子:

 用户 tbl (Id (int), LastName (string))
 Order tbl (Id (int), UserId (int), IsPaid (bool), DatePaid (Date, not null))

我写了一个 Sql 请求,但我担心我有 20k 的用户和大量的订单

我找到了所有没有债务的人,最后一次还款是两年。 现在我想将它们从常规列表中删除,以便保留需要我的用户。
这似乎是个坏主意

SELECT u."Id"
FROM "User" AS u
LEFT JOIN
   (SELECT *
    FROM "Order"
    WHERE "UserId" IN
       (SELECT "Id"
        FROM "User"
        WHERE "Id" NOT IN
           (SELECT DISTINCT "UserId"
            FROM "Order"
            WHERE "IsPaid" IS FALSE )
       )
    AND "DatePaid" > '2016-10-10'
   ) AS p
   ON p."UserId" = u."Id";

【问题讨论】:

  • 我猜你快到了。请标记您的数据库和一些示例数据。我们一定会帮助您改善答案。感谢您的努力。
  • 为什么嵌套选择中有IsConfirmedOnAccountingSystem 而不是外部查询中有它?也许我遗漏了一些东西,但感觉你有点过于复杂了。
  • 您能更正您的架构摘要吗?我猜 IsConfirmedOnAccountingSystem == IsPaid 和 DateConfirmed == DatePaid?
  • 抱歉,它必须是“IsPaid”而不是“IsConfirmedOnAccountingSystem”
  • 请说明您如何知道某人是否没有债务。并用您正在使用的数据库标记您的问题。

标签: sql postgresql


【解决方案1】:

我想你只是想要这样的东西:

select o.userid
from orders o
group by o.userid
having sum(case when o.isPaid then 1 else 0 end) = count(*) and -- all are paid
       max(o.paymentdate) < current_date - interval '2 year';

请注意,众所周知,日期函数是特定于数据库的。以上使用ANSI/ISO标准语法。

如果您想要关于用户的完整信息,那么您可以使用不同的结构:

select u.*
from users u
where not exists (select 1
                  from orders o
                  where o.userid = u.id and not u.ispaid
                 ) and
      not exists (select 1
                  from orders o
                  where o.userid = u.id and
                        u.paymentdate > current_date - interval '2 year'
                 );

【讨论】:

  • 好像忘了机会说那些没有任何订单的无用用户。但是这段代码看起来不错:)
  • @TomTom 。 . .第一个查询只返回有订单的用户。第二个返回那些根本没有订单的 plus 用户。
猜你喜欢
  • 1970-01-01
  • 2019-06-18
  • 2021-12-11
  • 2016-02-27
  • 2021-06-06
  • 1970-01-01
  • 1970-01-01
  • 2015-01-08
  • 2022-01-24
相关资源
最近更新 更多