简体   繁体   中英

How to fetch data by a conditional query(left join/right join/inner join/ multi select, … or) from multi table

I have a problem with conditional query and can't solve that and I need your help. I use mysql with innodb and I have some tables like bellow.

table1: ---------------------- uers_type_1 ----------------------

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

table 2: ---------------------- uers_type_2 ----------------------

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

table 3: ---------------------- user_request ----------------------

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

Now I need a query to fetch something like this: user request data with user first name and last name from users type tables

Result:

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

My query something like this but it's not work

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

I got a solution for your problem,

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' 

the point is that : try to point both tables in the query using left join and then in your select options choose where it should be used for fetching the data.

(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

hope that help you.

Having 2 user tables is going to perplex and frustrate you. While I don't know why you have them if it is possible consider moving them into to a single table. In any case, you can produce a single view of the user information by using a UNION ALL query such as this:

  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
  ;

That query might literally be used to create a view but that it is optional. That UNION ALL approach can be used as a derived table subquery in a query like the following. Notice how this simplifies access to the name columns.

  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
  ;

Another alternative is to use 2 left joins, one for each user table and include the user_type into each join as a condition of the join. Note here the names can be NULL due the way the left joins will work, so you can overcome that by seing COALESCE() or 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'
  ;

If you should choose to create a view, eg

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
  ;

Then subsequent queries become easier to assemble eg

  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 even if you do one day combine those 2 user tables into 1, you can just adjust that view and existing queries will not be broken.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM