如何在没有子查询的情况下在 SQL 中进行多个成员资格测试?
我确信这是一个非常简单的 SQL 问题,但恐怕我的 SQL 能力还达不到我能够弄清楚的水平。
我有一张销售订单表和一张客户表。每个销售订单都有一个为其开票客户的 ID,以及一个为其发货客户的 ID(它们可能相同,但大多数情况下不同 - 之间存在一对多关系) “收单至”和“发货至”[例如,假设我要向 Google 出售某些东西,“收单至”将是 Google 的山景城总部,但“发货至”可能是 Google 的日内瓦办事处。)
所以我'有一个查询基本上询问以下问题: “请提供销售订单表中的总销售额,其中该客户的收单方与 John Doe 关联,或者该客户的收货方与 John Doe 关联,但也没有收单方。”
我的查询相当简单(读:天真)
SELECT SUM(price) FROM salesOrders
WHERE
(
( salesOrders.BillTo IN (SELECT customerID FROM customers WHERE customers.salesman = 'JOHNDOE')
OR
(salesOrders.ShipTo IN (SELECT customerID FROM customers WHERE customers.salesman = 'JOHNDOE')
AND
salesOrders.BillTo NOT IN (SELECT customerID FROM customers WHERE customers.salesman = 'JOHNDOE')
)
)
查询有效,但它需要太长的时间(执行约 6 秒)。我几乎肯定有一种非常简单的方法可以提取子查询,这样我就不必将其重复三次,或者完全删除子查询并用联接替换它们,我只是不知道该怎么做。 :( 从好的方面来说,这对于其他人来说可能很容易:)
提前致谢。
I'm sure this is a very easy SQL question but I'm afraid my SQL-fu is still not up to snuff for me to be able to figure it out.
I have a table of sales orders and a table of customers. Each sales order has an ID for the customer to whom it will be billed, and an ID for the customer to whom it will be shipped (they may be the same, but most often not - there is a one-to-many relationship between a "bill to" and "ship to" [e.g. let's say I'm selling something to Google, the "bill to" would be Google's Mountain View headquarters, but the "ship to" might be Google's Geneva office.)
So I've got a query that basically asks the following question:
"Give me the total sales from the sales order table where this customer's Bill To is associated with John Doe or this customer's Ship To is associated with John Doe, but not the Bill To as well."
and the query I have is fairly straightforward (read: naive)
SELECT SUM(price) FROM salesOrders
WHERE
(
( salesOrders.BillTo IN (SELECT customerID FROM customers WHERE customers.salesman = 'JOHNDOE')
OR
(salesOrders.ShipTo IN (SELECT customerID FROM customers WHERE customers.salesman = 'JOHNDOE')
AND
salesOrders.BillTo NOT IN (SELECT customerID FROM customers WHERE customers.salesman = 'JOHNDOE')
)
)
The query works, but it just takes way too long (~6 sec to execute). I'm almost positive there is a very easy way to either extract the subquery so I don't have it triplicated or remove the subqueries altogether and replace them with joins, I just don't know how to do it. :( On the plus side, this might be easy points for someone out there :)
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我不知道您使用的是什么数据库引擎,但如果它功能强大,将允许您创建临时/变量表。
我相信您已经注意到,您使用了相同的 select 3 次,如果执行一次,将结果保存到临时表并在使用后将其删除,可能会更有用。
I do not know what database engine you are using, but if it is powerful will allow you tocreate temporary/variable tables.
I'm sure you have noticed, you are useing the same select 3 times, it might be more useful if performed once, save results to a temporary table and delete it after use.
最能提高性能的是拥有正确的索引。
你不会说你运行的是哪个 SQL 服务器,如果它是 SQL 2008,它会给你在查看查询计划时添加索引的提示。
我更喜欢使用存在,据我所知,使用它并没有太大的性能提升。您应该查看查询计划进行检查。
The thing that would do most performance boost is having the correct indexing.
You dont say which SQL server your running if it's SQL 2008 it will give you hints of index to add when looking at the query plan.
I Prefer using exists, there is not much performance gain using it as far as i have been able to tell. You should look at the queryplan to check.
假设您在
salesOrders
中有一个 id 列(此处简称为ID
):UNION 消除了重复项,因此
BillTo
的情况code> 与ShipTo
相同,不会计算两次。This assumes that you have an id column(s) in
salesOrders
(here referred to just asID
):UNION eliminates the duplicates, so cases where
BillTo
is identical toShipTo
will not be calculated twice.