【问题标题】:mysql - Finding count of 0 when using joined tablesmysql - 使用连接表时发现计数为 0
【发布时间】:2014-03-20 22:29:52
【问题描述】:

编辑我在这里用这个模式建立了一个 sqlfiddle:http://sqlfiddle.com/#!2/0726f2。我正在尝试选择客户 3、4、5、6。

考虑一个包含三个表的数据库:

customers
---------
id

seats
-----
id
buyer_id (fk to customers)
flight_id

flights
-------
id
datetime (This is the UTC time of the flight)

我正在努力寻找 未在 3 月份的任何航班上预订座位的客户。

此查询提供尚未预订任何航班座位的客户列表:

SELECT customers.id, count(seats.id) as seat_count FROM `customers` 
LEFT JOIN `seats` ON `seats`.`buyer_id` = `customers`.`id` 
LEFT JOIN `flights` ON `flights`.`id` = `seats`.`flight_id` 
GROUP BY customers.id
HAVING seat_count=0

我尝试使用此查询来查找未在 3 月 任何航班上预订座位的客户列表

SELECT customers.id, count(seats.id) as seat_count FROM `customers` 
LEFT JOIN `seats` ON `seats`.`buyer_id` = `customers`.`id` 
LEFT JOIN `flights` ON `flights`.`id` = `seats`.`flight_id` 
WHERE flights.datetime >= '2014-03-01 00:00:00'
AND flights.datetime <=   '2014-04-01 00:00:00'
GROUP BY customers.id
HAVING seat_count=0

但它返回一个空列表。我明白为什么:我正在选择一个已在 3 月份预订座位的客户列表,然后在该列表中查找尚未预订座位的客户。显然是一个空集。

同样将其添加到 WHERE 子句中

AND seats.is is null

我想不出一个正确的方法来做到这一点。

我试过了:

  • 以各种方式翻转 JOIN
  • 在 LEFT JOIN 语句中使用子查询。性能非常糟糕。
  • 尝试SELECT customers.id from customers where id not in ([above query]) MySql 使用关联子查询,性能也非常糟糕。

因为这包含在一个更大的搜索功能中,所以我无法从另一个方向(例如,从座位中选择并从那里出发)来解决这个问题。无法更改架构。

谢谢。

【问题讨论】:

  • 考虑提供适当的 DDL(和/或 sqlfiddle)以及所需的结果集
  • 好建议。我会尝试制作一个 sqlfiddle。

标签: mysql join


【解决方案1】:

你可以用NOT EXISTS点赞

SELECT *
FROM customers
WHERE NOT EXISTS (
  SELECT * FROM seats 
  INNER JOIN flights ON flights.id = seats.flight_id
  WHERE flights.datetime >= '2014-03-01 00:00:00'
  AND flights.datetime <=   '2014-04-01 00:00:00'
  AND seats.buyer_id = customers.id
)

here is a corresponding SQLFiddle.

顺便说一句,您至少应该在seats.buyer_id 上添加一个索引,因为这是您需要加入的列。使用命名索引,执行计划看起来并没有那么糟糕。

【讨论】:

  • 抱歉一定是在小提琴中错过了。我们的数据库被正确索引。我会试一试。谢谢。
【解决方案2】:

这行得通:

SELECT customers.id, count(seats.id) as seat_count FROM `seats` 
INNER JOIN (SELECT id FROM flights WHERE DATE(flights.datetime) >= '2014-03-01'
AND DATE(flights.datetime) <='2014-04-01') `flights` ON `flights`.`id` = `seats`.`flight_id` 
RIGHT JOIN customers ON customers.id=seats.buyer_id
GROUP BY customers.id
HAVING seat_count=0

这是fiddle

这是另一种方法:

SELECT customers.id FROM customers WHERE id NOT IN (SELECT seats.buyer_id FROM seats
INNER JOIN `flights` ON `flights`.`id` = `seats`.`flight_id` 
WHERE flights.datetime >= '2014-03-01 00:00:00'
AND flights.datetime <=   '2014-04-01 00:00:00')

第二个fiddle

【讨论】:

  • 抱歉,因为这是一个更大的搜索功能,我无法选择座位。谢谢。
  • @gmoore 并没有真正理解您对第一个查询有什么问题,您知道更多...添加了另一种方法,如果它对您有用,请不要...跨度>
猜你喜欢
  • 2021-10-30
  • 2012-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-26
  • 1970-01-01
  • 2015-10-26
相关资源
最近更新 更多