如何通过左连接知道选择范围内的哪个值?

时间:2012-03-06 20:25:05

标签: mysql sql

如果我有这个(MySQL)声明:

   SELECT h.*
     FROM houses h 
LEFT JOIN avail a ON (h.id = a.house_id
                 AND (    a.date_occupied = '2012-03-07'
                       OR a.date_occupied = '2012-03-08'
                       OR a.date_occupied = '2012-03-09'
                       OR a.date_occupied = '2012-03-10'))
    WHERE sleeps_count >= '1'
      AND active = 1
      AND a.house_id IS NULL
ORDER BY h.name

有没有办法让结果中返回的'date_occupied'匹配?或者我是否手动完成结果,然后找出实际上是哪个日期?

4 个答案:

答案 0 :(得分:4)

首先,它可能只是:

a.date_occupied IN ('2012-03-07', '2012-03-08', '2012-03-09', '2012-03-10')

或者:

a.date_occupied BETWEEN '2012-03-07' AND '2012-03-10'

要确定哪个日期是匹配,只需检查a.date_occupied。由于JOIN条件已经知道它在适当的范围内,因此您只需将其包含在SELECT列表中即可。

答案 1 :(得分:1)

只需将该列添加到SELECT列表中:

SELECT h.*, a.date_occupied
     FROM houses h 
LEFT JOIN avail a

更新:,正如Guffa在评论中指出的那样,您的查询将排除所有符合加入条件的行。我起初错过了。要通过不同的条件返回与date_occupied记录相关的avail记录的信息(例如house),您需要另一个加入以公开此数据:

SELECT h.*, b.date_occupied
     FROM houses h 
LEFT JOIN avail a ON (h.id = a.house_id
                 AND (    a.date_occupied = '2012-03-07'
                       OR a.date_occupied = '2012-03-08'
                       OR a.date_occupied = '2012-03-09'
                       OR a.date_occupied = '2012-03-10'))
LEFT JOIN avail b ON h.id = b.house_id
    WHERE sleeps_count >= '1' -- These columns may need to be qualified 
      AND active = 1          -- if they're on the avail table
      AND a.house_id IS NULL
ORDER BY h.name

或者,如果您要查找avail条记录中的信息,但只想排除那些date_occupied值的记录,那么在加入后添加该约束会更加简单(即WHERE子句!)

SELECT h.*, a.date_occupied
     FROM houses h 
LEFT JOIN avail a ON h.id = a.house_id
    WHERE sleeps_count >= '1'
      AND active = 1
      AND a.date_occupied NOT IN ('2012-03-07','2012-03-08','2012-03-09','2012-03-10')
ORDER BY h.name

如果这些都不够,那么我担心我从根本上误解了你所要求的东西 - 这个问题可能需要澄清。 :)

答案 2 :(得分:1)

您只需在选择列表中添加列date_occupied

   SELECT h.*, a.date_occupied
     FROM houses h 
LEFT JOIN avail a ON (h.id = a.house_id
                 AND (    a.date_occupied = '2012-03-07'
                       OR a.date_occupied = '2012-03-08'
                       OR a.date_occupied = '2012-03-09'
                       OR a.date_occupied = '2012-03-10'))
    WHERE sleeps_count >= '1'
      AND active = 1
      AND a.house_id IS NULL
ORDER BY h.name

答案 3 :(得分:0)

如果您想知道哪个日期匹配,那么您需要从WHERE子句中删除它,因为它当前导致具有匹配日期的行从结果集中排除:

  AND a.house_id IS NULL

一旦这样做,您可以将a.date_occupied列添加到select子句中,以查看匹配的日期(如果有)。如果没有匹配的日期,则该列将为NULL。由于多个日期可以匹配,我建议按h.id分组并使用GROUP_CONCAT()将所有dats组合到一行。

这是最后的查询:

   SELECT h.*, group_concat(distinct a.date_occupied order by a.date_occupied)
     FROM houses h 
LEFT JOIN avail a ON (h.id = a.house_id
                 AND (    a.date_occupied = '2012-03-07'
                       OR a.date_occupied = '2012-03-08'
                       OR a.date_occupied = '2012-03-09'
                       OR a.date_occupied = '2012-03-10'))
    WHERE sleeps_count >= '1'
      AND active = 1
GROUP BY h.id
ORDER BY h.name;