单个查询连接表中没有键的所有记录和具有匹配键的记录

时间:2009-10-02 17:17:10

标签: sql ruby-on-rails mysql searchlogic

我的旅行有很多住宿。我需要一个查询返回所有没有指定居住信息的行程。以及符合指定居住地的所有旅行。

我可以从此查询中获得第一个:

SELECT * FROM `trips` WHERE (((NOT EXISTS (SELECT id FROM residencies WHERE trips.id = residencies.trip_id))

但要获得第二个,我还需要添加这个位:

INNER JOIN `residencies` ON (`trips`.`id` = `residencies`.`trip_id`)

在WHERE子句之前添加连接是要求具有驻留ID且没有驻留ID的结果。这显然没有任何回报。那么如何编写这个来获取一个查询中的完整结果集呢?此处不允许存储过程。

我正在使用Rails,所以如果答案是Rails特定的话,这是一个奖励(但绝对不是必需的)。如果有人可以展示如何使用searchlogic插件完成这项工作,那将是一个巨大的奖励。

目前,我将第一个要求作为命名范围:

Trip.named_scope :residencies_empty, :conditions => ['NOT EXISTS (SELECT id FROM residencies WHERE trips.id = residencies.trip_id)']

第二个要求可通过searchlogic获得:

Trip.residences_id_equals(id)

理想的解决方案是searchlogic范围,如下所示:

Trip.residencies_null_or_residencies_id_equals(id)

3 个答案:

答案 0 :(得分:0)

TRY:

SELECT * FROM `trips`
    LEFT JOIN  residencies ON trips.id = residencies.trip_id

您将从trips的所有列中获取数据,但数据仅填充在存在行的驻留列中,如果不存在驻留行,则这些列将为空。

答案 1 :(得分:0)

您是否尝试过使用UNION来合并两个查询的结果?

答案 2 :(得分:0)

我建议使用另一个“EXIST”来进行具体居住的旅行:

SELECT * FROM `trips` WHERE 
  (NOT EXISTS (SELECT id FROM residencies WHERE trips.id = residencies.trip_id))
  OR
  (EXISTS (SELECT id FROM residencies WHERE trips.id = residencies.trip_id 
           AND other_criteria_for_specific_residency)
  )

这似乎是最具可读性的解决方案,但如果性能很重要,则应检查EXPAIN以查看其优化方式(与MySql中的大多数复杂查询一样)。