【问题标题】:COnditional JOIN query in MySQLMySQL中的条件连接查询
【发布时间】:2019-09-20 06:11:52
【问题描述】:

我有两个mysql表

用户:

|--------------------------------|
| id | name  | type | ruser_type |
|--------------------------------|
|  1 | Admin | a    |            |
|  2 |       | r    |      c     |
|--------------------------------|

客户

|-------------------------|
|  id  |  name  | user_id | 
|-------------------------|
|  1   |  Sam   |    2    |
|-------------------------|

如果user.type 是“a”或“s”,则其名称在用户表中的管理员用户。

如果user.type 是'r' 而ruser_type 是'c',那么它的普通用户在客户表中有customer.user_id = user.id 的关系

我想要一个运行条件连接的查询。 如果user.type 是 'a' 或 's',则将从用户表中获取名称。

如果 user.type 是 'r' 且 ruser_type 是 'c',则名称将从带有 JOIN 条件 customer.user_id = user.id 的客户表中获取。

为此,我写了一个这样的查询:-

SELECT users.fname as adminFname, customers.fname as customerFname, users.type FROM users
LEFT JOIN customers ON (customers.user_id = users.id AND 
                            ( 
                                (users.type = 'r' AND users.ruser_type = 'c') 
                                    OR users.type = 'a' 
                                    OR users.type = 's'
                            )
                       )
                        WHERE users.id = 1

是否有可能进一步优化查询?

另外,如何使用 Laravel eloquent 编写这个查询?

【问题讨论】:

  • 一种懒惰的方法是UNION 2 个查询的结果。一份给管理员,一份给客户。
  • 可以在那里找到另一个解决方案:stackoverflow.com/questions/4706100/…
  • 与所有相关表的 SHOW CREATE TABLE 语句一样,关于查询优化的问题总是需要给定查询的 EXPLAIN。

标签: mysql laravel-5.7


【解决方案1】:

FWIW,我觉得这更容易阅读......

SELECT u.fname adminFname
     , c.fname customerFname
     , u.type 
  FROM users u
  LEFT 
  JOIN customers c
    ON c.user_id = u.id 
 WHERE u.id = 1
   AND (
        (u.type = 'r' AND u.ruser_type = 'c')
     OR (u.type IN('a','s'))
       )

【讨论】:

    【解决方案2】:

    我写了两个sql查询希望对你有帮助

    SELECT CASE CU.type WHEN 'a' OR 's' THEN CU.name END AS name,
    CASE WHEN CU.type = 'r' AND CU.ruser_type = 'c' THEN CR.name END AS cust_name, CU.type
    FROM 
    user AS CU
    LEFT JOIN customer AS CR ON CR.user_id = CU.id
    

    在这你会得到这样的结果,

    name    cust_name   type
              Sam         r
    Admin                 a
    

    我已经写了另一个这样的查询,

    SELECT CASE WHEN CU.type  = 'a' OR 's' THEN CU.name ELSE CR.name END AS name, CU.type
    FROM 
    user AS CU
    LEFT JOIN customer AS CR ON CR.user_id = CU.id
    

    在这你会得到这样的结果

    name    type
    Sam     r
    Admin   a
    

    数据库文件链接 https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=b02d931b68a4f70d8b4a84144c60a572

    【讨论】:

    • 您可以在两个查询中使用带有 id 的 where 条件来获得 id 明智的结果。
    【解决方案3】:

    这将为您提供所有用户所需的结果:

    SELECT u.fname adminFname
         , c.fname customerFname
         , u.type 
      FROM users u
      LEFT JOIN customers c
        ON (u.type = 'r' AND u.ruser_type = 'c' AND c.user_id = u.id)
    

    根据需要添加where条件。

    您甚至可以进一步简化它以在输出中获得常见的 firstName 列:

    SELECT COALESCE(u.fname, c.fname) firstName, u.type 
      FROM users u
      LEFT JOIN customers c
        ON (u.type = 'r' AND u.ruser_type = 'c' AND c.user_id = u.id)
    

    【讨论】:

      猜你喜欢
      • 2011-06-25
      • 1970-01-01
      • 2016-05-07
      • 2021-10-17
      • 1970-01-01
      • 2018-12-15
      • 2011-03-12
      • 2018-03-09
      • 2014-06-15
      相关资源
      最近更新 更多