sql - 如何更好地优化 SQL 查询?
问题描述
我写了请求,但恐怕它可能非常未优化,我会遇到问题。
任务:查找没有债务且最后一次付款超过 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";
解决方案
我想你只是想要这样的东西:
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'
);
推荐阅读
- python-3.x - 计算一个样本单侧测试的功效
- c# - ConfigurationManager.AppSettings
- c# - FxCopAnalyzers 和 .editorconfig 文件是否应该同步?
- vue.js - 使用 Vuetify 将标签中的内容居中
- javascript - Javascript 如何实现变量绑定?
- ruby-on-rails - 为什么 RSpec 会抛出 InvalidSignature 错误?
- hibernate - 如何使用 JPA Criteria Builder 编写带有附加计数列的查询
- javascript - 如何在电子中启用位置权限?
- php - 无法使用 php 从我的硬盘驱动器中找到文件
- c# - 如何在 Asp Net Core 3.1 Web API 中的派生类型列表上实现数据验证属性