条件JOIN不同的表
Posted
技术标签:
【中文标题】条件JOIN不同的表【英文标题】:Conditional JOIN different tables 【发布时间】: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
【问题讨论】:
【参考方案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/1 和 http://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
【讨论】:
以上是关于条件JOIN不同的表的主要内容,如果未能解决你的问题,请参考以下文章