好的我有几张桌子。我只展示相关领域:
items:
----------------------------------------------------------------
name | owner_id | location_id | cab_id | description |
----------------------------------------------------------------
itm_A | 11 | 23 | 100 | Blah |
----------------------------------------------------------------
.
.
.
users:
-------------------------
id | name |
-------------------------
11 | John |
-------------------------
.
.
.
locations
-------------------------
id | name |
-------------------------
23 | Seattle |
-------------------------
.
.
.
cabs
id | location_id | name
-----------------------------------
100 | 23 | Cool |
-----------------------------------
101 | 24 | Cool |
-----------------------------------
102 | 24 |thecab |
-----------------------------------
我正在尝试选择来自西雅图或丹佛的所有物品(及其所有者信息),但如果他们在西雅图,他们只能在驾驶室NAMED Cool,如果他们在丹佛,他们只能在名为'thecab'的出租车(不是丹佛和酷)。
此查询不起作用,但我希望它能解释我要完成的任务:
SELECT DISTINCT
`item`.`name`,
`item`.`owner_id`,
`item`.`description`,
`user`.`name`,
IF(`loc`.`name` = 'Seattle' AND `cab`.`name` = 'Cool',1,0) AS `cab_test_1`,
IF(`loc`.`name` = 'Denver' AND `cab`.`name` = 'thecab',1,0) AS `cab_test_2`,
FROM `items` AS `item`
LEFT JOIN `users` AS `user` ON `item`.`owner_id` = `user`.`id`
LEFT JOIN `locations` AS `loc` ON `item`.`location_id` = `loc`.`location_id`
LEFT JOIN `cabs` AS `cab` ON `item`.`cab_id` = `cabs`.`id`
WHERE (`loc`.`name` IN ("Seattle","Denver")) AND `cab_test_1` = 1 AND `cab_test_2` = 1
我宁愿摆脱IF也是可能的。它似乎无穷无尽,看起来很笨,如果我有很多位置\名称对,它就不可扩展
答案 0 :(得分:1)
试试这个:
SELECT DISTINCT
item.name,
item.owner_id,
item.description,
user.name
FROM items AS item
LEFT JOIN users AS user ON item.owner_id = user.id
LEFT JOIN locations AS loc ON item.location_id = loc.id
LEFT JOIN cabs AS cab ON item.cab_id = cabs.id
WHERE ((loc.name = 'Seattle' AND cab.name = 'Cool')
OR (loc.name = 'Denver' AND cab.name = 'thecab'))
答案 1 :(得分:0)
我的第一个想法是将位置对和出租车名称存储在一个单独的表中。好吧不是一个表,而是由子查询生成的派生表。
您仍然存在将测试结果转换为单独列的问题。通过使用mysql布尔表达式可以简化代码,从而无需case
或if
。
因此,方法是使用相同的联接(尽管不需要left join
,因为cab.name
上的比较将它们转换为内部联接)。然后添加您要查找的对的表以及该对的“测试名称”。最后一步是明确的group by
并检查每个测试是否满足条件:
SELECT i.`name`, i.`owner_id`, i.`description`, u.`name`,
max(pairs.test_name = 'test_1') as cab_test_1,
max(pairs.test_name = 'test_2') as cab_test_2
FROM `items` i LEFT JOIN
`users` u
ON i.`owner_id` = u.`id` LEFT JOIN
`locations` l`
ON i.`location_id` = l.`location_id` left join
`cabs` c
ON i.`cab_id` = c.`id` join
(select 'test_1' as testname, 'Seattle' as loc, 'cool' as cabname union all
select 'test_2', 'Denver', 'thecab'
) pairs
on l.name = pairs.name and
l.cabname = c.name
group by i.`name`, i.`owner_id`, i.`description`, u.`name`;
要添加其他对,请将它们添加到pairs
表中,并在select
中为测试标记添加适当的行。