【问题标题】:Conditional JOIN different tables条件JOIN不同的表
【发布时间】:2012-05-03 23:31:39
【问题描述】:

我想知道用户是否在 任何 2 个相关表中都有条目。

表格

USER (user_id)
EMPLOYEE (id, user_id)
STUDENT (id, user_id)

用户可能有员工和/或学生条目。如何在一个查询中获取该信息? 我试过了:

select * from [user] u
inner join employee e 
    on e.user_id = case when e.user_id is not NULL 
                        then u.user_id 
                        else null 
                   end
inner join student s 
    on s.user_id = case when s.user_id is not NULL 
                        then u.user_id 
                        else null 
                   end

但它只会返回在两个表中都有条目的用户。

SQL Fiddle example

【问题讨论】:

    标签: sql sql-server-2008 join conditional


    【解决方案1】:

    如果您将员工表和学生表视为一个表,则可以使用左连接:

    select * 
    from user u
    left join 
    (
       select 'Employee' as UserType,
              id,
              user_id
         from employee e 
        union all
       select 'Student',
              id,
              user_id
         from student s 
    ) r
      ON u.user_id = r.user_id
    

    【讨论】:

    • 最佳解决方案。 UNION ALL 将解决所有有条件的工作......太好了。谢谢。
    【解决方案2】:

    你可以使用外连接:

    select *
      from USER u
      left outer join EMPLOYEE e ON u.user_id = e.user_id
      left outer join STUDENT s ON u.user_id = s.user_id
     where s.user_id is not null or e.user_id is not null
    

    或者(如果您对 EMPLOYEE 或 STUDENT 表中的数据不感兴趣)

    select *
      from USER u
     where exists (select 1 from EMPLOYEE e where e.user_id = u.user_id)
        or exists (select 1 from STUDENT s  where s.user_id = u.user_id)
    

    【讨论】:

      【解决方案3】:

      UNION 怎么样,你写成 2 个单独的 SELECT 语句

      例如: SELECT * FROM User U JOIN Employee E ON E.User_Id = U.User_Id UNION SELECT * FROM User U JOIN student S ON S.User_Id = U.User_Id 我不明白你为什么需要 CASE 声明,它看起来是多余的。如果您想要所有用户并显示空值,请使用 LEFT OUTER JOIN。

      【讨论】:

        【解决方案4】:

        如果您想将所有用户数据放在一起,您可能有:

        SELECT 
            user_id
            ,'Employee' AS Source
        FROM 
            employee
        UNION 
        SELECT 
            user_id
            ,'Student' AS Source
        FROM 
            student
        

        http://sqlfiddle.com/#!3/90216/22

        这也可以通过完全连接和 CASE 语句来完成:

        SELECT 
            ISNULL(e.user_id,s.user_id) AS user_id
            ,CASE WHEN e.user_id IS NULL THEN 'Student' 
                ELSE 'Employee'
            END AS SOURCE
        FROM 
            employee AS e 
            FULL JOIN student AS s
                ON s.user_id = e.user_id
        

        http://sqlfiddle.com/#!3/90216/29

        后者会将既是学生又是雇员的人组合成一排,并称他们为雇员。比较:

        http://sqlfiddle.com/#!3/2aa3e/1http://sqlfiddle.com/#!3/2aa3e/2

        我让用户 1 成为学生和员工

        【讨论】:

          【解决方案5】:

          这样的解决方案也可以帮助你。

          SELECT  S.*, P.*
          
          ,CASE
              WHEN S.ShipmentType = 'import' THEN SP.SupplierName
              WHEN S.ShipmentType = 'export' THEN C.CustomerName
          END AS ShipmentDesination
          
          FROM            tblShippments   S 
          INNER JOIN      tblProducts     P   ON S.productId = P.productID  
          LEFT OUTER JOIN tblCustomers    C   ON S.companyId = C.customerId AND S.ShipmentType = 'export'
          LEFT OUTER JOIN tblSuppliers    SP  ON S.companyId = SP.supplierId AND S.ShipmentType = 'import'
          

          【讨论】:

            【解决方案6】:
            SELECT   OrderID, Quantity,  O.ProductID , ProductName,
            CASE
            WHEN Quantity > 3 THEN 'The quantity is More than 3'
            WHEN Quantity = 3 THEN 'The quantity is Equal to  3'
            ELSE 'The quantity is Less than 3'
            END AS QuantityText
            
            FROM            tb_OrderDetail O 
            INNER JOIN      tb_Product     P   ON O.ProductID = P.ProductID
            

            【讨论】:

            • 请提供有关您的解决方案的更多详细信息。仅发布代码并不是回答问题的好方法。
            【解决方案7】:

            适用于 mysql v5.6+
            架构:

            CREATE TABLE USER (user_id INT);
            CREATE TABLE employee (id INT, user_id INT);
            CREATE TABLE student (id INT, user_id INT);
            
            INSERT INTO USER SELECT 1;
            INSERT INTO USER SELECT 2;
            INSERT INTO USER SELECT 3;
            INSERT INTO USER SELECT 4;
            
            INSERT INTO employee SELECT 1, 1;
            INSERT INTO employee SELECT 2, 4;
            
            INSERT INTO student SELECT 1, 2;
            

            第一个解决方案 ,完全外连接不适用于mysql v5.6+:

             SELECT 
                IF(e.user_id IS NULL,s.user_id,e.user_id) AS user_id
                ,CASE WHEN e.user_id IS NULL THEN 'Student' 
                    ELSE 'Employee'
                END AS SOURCE
            FROM 
                employee AS e 
                LEFT JOIN student AS s
                    ON (s.user_id = e.user_id)
                UNION
                    SELECT 
                IF(e.user_id IS NULL,s.user_id,e.user_id) AS user_id
                ,CASE WHEN e.user_id IS NULL THEN 'Student' 
                    ELSE 'Employee'
                END AS SOURCE
                FROM 
                employee AS e 
                 RIGHT JOIN student AS s
                    ON (s.user_id = e.user_id)
            

            替代解决方案:

            SELECT   IF(e.user_id IS NULL,s.user_id,e.user_id) AS user_id,
             CASE WHEN e.user_id IS NULL THEN 'Student' 
                        ELSE 'Employee'
                    END AS SOURCE
             FROM   USER AS u
             LEFT OUTER JOIN employee e ON (u.user_id = e.user_id) 
             LEFT OUTER JOIN student s ON (u.user_id = s.user_id) 
             WHERE s.user_id IS NOT NULL OR e.user_id IS NOT NULL
            

            其他替代解决方案:

             SELECT u.user_id,SOURCE 
            FROM USER u
            INNER JOIN 
            (
               SELECT 'Employee' AS SOURCE,id,user_id FROM employee e 
                UNION ALL
               SELECT 'Student',id,user_id  FROM student s 
            ) r ON u.user_id = r.user_id
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2018-12-11
              • 1970-01-01
              • 2023-03-17
              • 2020-06-15
              • 1970-01-01
              • 2019-07-11
              • 2011-04-15
              • 1970-01-01
              相关资源
              最近更新 更多