【问题标题】:How would I execute this complex conditional multi-table MySQL join (queries provided)?我将如何执行这个复杂的条件多表 MySQL 连接(提供的查询)?
【发布时间】:2013-06-21 11:00:41
【问题描述】:

好的,我有几张桌子。我只显示相关字段:

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 |
-----------------------------------

我正在尝试选择来自西雅图或丹佛的所有物品(及其所有者信息),但如果它们在西雅图,它们只能在名为 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 是可能的。如果我有很多位置\名称对,它似乎效率低下,看起来很笨重,并且不可扩展

【问题讨论】:

    标签: mysql sql join distinct


    【解决方案1】:

    我的第一个想法是将位置和出租车名称对存储在单独的表中。不完全是一个表,而是一个由子查询生成的派生表。

    您仍然存在将测试结果转换为单独列的问题。可以通过使用 mysql 布尔表达式来简化代码,这样就不需要 caseif

    因此,方法是使用与您相同的连接(尽管不需要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 中添加适当的行作为测试标志。

    【讨论】:

      【解决方案2】:

      试试这个:

      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'))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-06-18
        • 2023-03-14
        • 1970-01-01
        • 2019-12-25
        • 2018-03-09
        • 1970-01-01
        • 2018-10-14
        • 2012-11-29
        相关资源
        最近更新 更多