如何通过条件查询(左连接/右连接/内连接/多选,......或)从多表中获取数据

时间:2017-10-21 13:53:27

标签: mysql if-statement conditional

条件查询存在问题但无法解决,我需要你的帮助。 我在innodb中使用了mysql,我有一些像bellow这样的表。

表1: ---------------------- uers_type_1 ----------------------

user_id int(11) primary auto_increment
firstname varchar(15)
lastname varchar(20)
.
.
.

表2: ---------------------- uers_type_2 ----------------------

user_id int(11) primary auto_increment
firstname varchar(15)
lastname varchar(20)
.
.
.

表3: ---------------------- user_request ----------------------

request_id int(11) primary auto_increment
user_type enum("ut1","ut2")
user_id int(11)
request text

现在我需要一个查询来获取这样的东西: 用户请求具有用户名和用户类型表的姓氏的数据

结果:

-----------------------------------------------
- firstName - lastName - request_id - request -
-----------------------------------------------
- Robert    - De Niro  - 10         - some request.
- Will      - Smith    - 93         - some request.
.
.
.

我的查询类似这样,但它不起作用

SELECT r.request_id , r.request, (
 execute(
  concat('select u.first_name AS firstName, u.lastname AS lastName from ', 
           (SELECT CASE r.user_type WHEN 'ut1' 
           THEN 'uers_type_1' WHEN 'ut2' THEN 'uers_type_2' END), 
           ' u WHERE u.user_id = ', r.user_id, ''
  )
 )
)
FROM `user_request` r
WHERE 1

2 个答案:

答案 0 :(得分:1)

我找到了解决问题的方法,

select user_request.r_id , user_request.request,
(select Case user_request.user_type when 'u1' then user_type_1.fistname else user_type_2.firstname end ) as name
from user_request 
left JOIN user_type_1 on user_request.user_id = user_type_1.id and user_request.user_type = 'u1' 
left JOIN user_type_2 on user_request.user_id = user_type_2.id and user_request.user_type = 'u2' 

重点是: 尝试使用左连接指向查询中的两个表,然后在您的选择选项中选择它应该用于获取数据的位置。

(select Case user_request.user_type when 'u1' then user_type_1.firstname else user_type_2.firstname end ) as name,
(select Case user_request.user_type when 'u1' then user_type_1.lastname else user_type_2.lastname end ) as family
希望能帮到你。

答案 1 :(得分:1)

拥有2个用户表会让你感到困惑和沮丧。虽然我不知道为什么你有它们,如果有可能考虑将它们移动到一个表中。在任何情况下,您都可以使用UNION ALL查询生成单个用户信息视图,如下所示:

  SELECT
        'ut1' AS user_type
      , user_id
      , firstname
      , lastname
  FROM user_type_1
  UNION ALL
  SELECT
        'ut2' AS user_type
      , user_id
      , firstname
      , lastname
  FROM user_type_2
  ;

该查询可能实际上用于创建view,但它是可选的。 UNION ALL方法可以在查询中用作derived table子查询,如下所示。请注意这是如何简化对名称列的访问。

  SELECT
        user_request.r_id
      , user_request.request
      , u.firstname                ## simple to access
      , u.lastname                 ## simple to access
  FROM user_request AS ur
  INNER JOIN (
        SELECT
              'ut1' AS user_type
            , user_id
            , firstname
            , lastname
        FROM user_type_1
        UNION ALL
        SELECT
              'ut2' AS user_type
            , user_id
            , firstname
            , lastname
        FROM user_type_2
  ) AS u ON ur.user_type = u.user_type
        AND ur.user_id = u.user_id
  ;

另一种方法是使用2个左连接,每个用户表一个,并在每个连接中包含user_type作为连接的条件。请注意,由于左连接的工作方式,名称可以为NULL,因此您可以通过查看COALESCE()IFNULL()

来解决这个问题。
  SELECT
        ur.r_id
      , ur.request
      , COALESCE(ut1.fistname,ut2.firstname) firstname
      , COALESCE(ut1.lastname,ut2.lastname) lastname
  FROM user_request as ur
  LEFT JOIN user_type_1 as ut1 ON ur.user_id = ut1.id
        AND ur.user_type = 'ut1'
  LEFT JOIN user_type_2 as ut2 ON ur.user_id = ut2.id
        AND ur.user_type = 'ut2'
  ;

如果您应该选择创建视图,例如

CREATE OR REPLACE VIEW users_all_v
AS
  SELECT
        'ut1' AS user_type
      , user_id
      , firstname
      , lastname
  FROM user_type_1
  UNION ALL
  SELECT
        'ut2' AS user_type
      , user_id
      , firstname
      , lastname
  FROM user_type_2
  ;

然后后续查询变得更容易组装,例如

  SELECT
        user_request.r_id
      , user_request.request
      , u.firstname                ## simple to access
      , u.lastname                 ## simple to access
  FROM user_request AS ur
  INNER JOIN users_all_v AS u ON ur.user_type = u.user_type
        AND ur.user_id = u.user_id
  ;

AND 即使您有一天将这两个用户表合并为1,您也可以调整该视图,并且不会破坏现有查询。

相关问题