在表users
,stu_master
,stu_info
,emp_master
和emp_info
下方显示。
用户
stu_master
stu_master_user_id
= users.user_id
stu_info
stu_info_id
= stu_master.stu_master_stu_info_id
emp_master
em_user_id
= users.user_id
emp_info
emp_info_id
= emp_master.em_emp_info_id
我使用以上5个表进行单个查询获得用户名或姓;
我有两种类型的用户,一种是Student
,另一种是Employee
,其登录详细信息存储在单个表中,其名称为Users
。但是我根据用户类型在两个不同的表中存储名/姓相关的详细信息存储。如果用户类型为 S 。我将使用stu_info
表在stu_master
中获得名/姓,因为user_id
关系在stu_master表中可用,其他明智的用户类型是E
,在{中获取名/姓{1}}使用emp_info
表因为emp_master表中的emp_master
关系。
我已尝试以下查询,但未获得预期结果。
user_id
上述查询返回SELECT user_id as UserId, stu_first_name as FirstName, stu_last_name as LastName, user_type as UserType FROM `users`
LEFT JOIN stu_master tsm ON (stu_master_user_id = user_id AND `user_type` = 'S')
LEFT JOIN stu_info tsi ON (tsm.stu_master_stu_info_id = tsi.stu_info_id)
UNION ALL
SELECT user_id as UserId, emp_first_name as FirstName, emp_last_name as LastName, user_type as UserType FROM `users`
LEFT JOIN emp_master tem ON (em_user_id = user_id AND `user_type` = 'E')
LEFT JOIN emp_info tei ON (tem.em_id = tei.emp_info_id)
WHERE `user_id` IN (1, 2, 3, 4, 5, 6);
和all student
。
显示输出
我只使用任何一个查询获得名字(1,2,3,4,5,6)的名/姓。
请给我任何类型的单一查询以达到我的要求或修改我的上述查询。
答案 0 :(得分:3)
如果您想要所有学生和当前架构中的所有雇主,那么您可以直接离开:
SELECT tu.user_id as UserId,
tsi.stu_first_name as FirstName,
tsi.stu_last_name as LastName,
tu.user_type as UserType
FROM users tu
LEFT JOIN stu_master tsm
ON tsm.stu_master_user_id = tu.user_id
LEFT JOIN stu_info tsi
ON tsi.stu_info_id = tsm.stu_master_stu_info_id
WHERE tu.user_type = 'S'
UNION ALL
SELECT tu.user_id as UserId,
tei.emp_first_name as FirstName,
tei.emp_last_name as LastName,
tu.user_type as UserType
FROM users tu
LEFT JOIN emp_master tem
ON tem.em_user_id = tu.user_id
LEFT JOIN emp_info tei
ON tei.emp_info_id = tsm.em_emp_info_id
WHERE tu.user_type = 'E'
在您的查询中,您将user_type条件放在LEFT JOIN中,因此仍会返回另一种类型的记录(使用NULLed名称)。您的WHERE也仅适用于第二个SELECT。
如果你想在两个SELECTS上添加一个条件,你需要将它复制为两个WHERE,或者将两个UNIONed语句用一个WHERE包装在外部SELECT中。
其他选项
假设员工或学生没有丢失/重复的信息记录,您实际上可以将这些LEFT JOIN更改为直接JOIN并删除WHERE:
SELECT tu.user_id as UserId,
tsi.stu_first_name as FirstName,
tsi.stu_last_name as LastName,
tu.user_type as UserType
FROM users tu
JOIN stu_master tsm
ON tsm.stu_master_user_id = tu.user_id
JOIN stu_info tsi
ON tsi.stu_info_id = tsm.stu_master_stu_info_id
/* WHERE tu.user_type = 'S' /* Optional */
UNION ALL
SELECT tu.user_id as UserId,
tei.emp_first_name as FirstName,
tei.emp_last_name as LastName,
tu.user_type as UserType
FROM users tu
JOIN emp_master tem
ON tem.em_user_id = tu.user_id
JOIN emp_info tei
ON tei.emp_info_id = tsm.em_emp_info_id
/* WHERE tu.user_type = 'E' /* Optional */
事实上,你可以做到:
SELECT tsm.stu_master_user_id as UserId,
tsi.stu_first_name as FirstName,
tsi.stu_last_name as LastName,
'S' as UserType
FROM stu_master tsm
ON tsm.stu_master_user_id = tu.user_id
JOIN stu_info tsi
ON tsi.stu_info_id = tsm.stu_master_stu_info_id
UNION ALL
SELECT tem.em_user_id as UserId,
tei.emp_first_name as FirstName,
tei.emp_last_name as LastName,
'E' as UserType
FROM emp_master tem
ON tem.em_user_id = tu.user_id
JOIN emp_info tei
ON tei.emp_info_id = tsm.em_emp_info_id
老实说,我认为你可以重新审视你的架构。你有很多奇怪的事情在继续。
大概一个员工/学生只能有一个信息记录,那么是否需要多对多样式链接表(emp_master / student_master)?
您实际上可以将user_id用作emp_info / student_info表中用户的PK和FK:
然后您的查询可能是:
SELECT tu.user_id, ts.first_name, ts.last_name, tu.user_type
FROM users tu
JOIN student ts
ON ts.user_id = tu.user_id
/* WHERE tu.user_type = 'S' /* Optional */
UNION ALL
SELECT tu.user_id, te.first_name, te.last_name, tu.user_type
FROM users tu
JOIN employee te
ON te.user_id = tu.user_id
/* WHERE tu.user_type = 'E' /* Optional */
或:
SELECT user_id, first_name, last_name, 'S' AS user_type
FROM student
UNION ALL
SELECT user_id, first_name, last_name, 'E' AS user_type
FROM employee
如果您考虑将公共字段first_name和last_name移动到users表本身,也值得一提:
- users - user_id, user_type, first_name, last_name
然后最终你会离开:
SELECT user_id, first_name, last_name, user_type
FROM users
答案 1 :(得分:3)
你真的很亲密,你甚至不需要工会。
这里有三种使用case语句和一种使用NVL()的方法,一种使用内联视图(如果你不能更改表结构,我会使用内联视图,它&#39 ;应该预先形成最好的。但是,如果要抓取的用户列表足够大,您可能希望在内联视图的每个select语句中添加where子句的附加副本。)
SELECT `user_id` as UserId
, (CASE WHEN `user_type` = 'S' THEN `stu_first_name`
WHEN `user_type` = 'E' THEN `emp_first_name`
END) as FirstName
, (CASE WHEN `user_type` = 'S' THEN `stu_last_name`
WHEN `user_type` = 'E' THEN `emp_last_name`
END) as LastName
, user_type as UserType
FROM `users`
LEFT JOIN stu_master tsm ON (stu_master_user_id = user_id AND `user_type` = 'S')
LEFT JOIN stu_info tsi ON (tsm.stu_master_stu_info_id = tsi.stu_info_id)
LEFT JOIN emp_master tem ON (em_user_id = user_id AND `user_type` = 'E')
LEFT JOIN emp_info tei ON (tem.em_id = tei.emp_info_id)
WHERE `user_id` IN (1, 2, 3, 4, 5, 6);
SELECT `user_id` as UserId
, NVL(`stu_first_name`,`emp_first_name`) as FirstName
, NVL(`stu_last_name`,`emp_last_name`) as LastName
, user_type as UserType
FROM `users`
LEFT JOIN stu_master tsm ON (stu_master_user_id = user_id AND `user_type` = 'S')
LEFT JOIN stu_info tsi ON (tsm.stu_master_stu_info_id = tsi.stu_info_id)
LEFT JOIN emp_master tem ON (em_user_id = user_id AND `user_type` = 'E')
LEFT JOIN emp_info tei ON (tem.em_id = tei.emp_info_id)
WHERE `user_id` IN (1, 2, 3, 4, 5, 6);
SELECT `user_id` as UserId
, `FirstName` as FirstName
, `LastName` as LastName
, `user_type` as UserType
FROM `users`
LEFT JOIN
(
SELECT 'S' as user_type
, stu_master_user_id as user_id
, stu_first_name as FirstName
, stu_last_name as LastName
FROM stu_master tsm
INNER JOIN stu_info tsi ON (tsm.stu_master_stu_info_id = tsi.stu_info_id)
UNION ALL
SELECT 'E' as user_type
, em_user_id as user_id
, emp_first_name as FirstName
, emp_last_name as LastName
FROM emp_master tem
INNER JOIN emp_info tei ON (tem.em_id = tei.emp_info_id)
) `User_info` USING (user_id, user_type)
WHERE `user_id` IN (1, 2, 3, 4, 5, 6);
;
下面是我用来在sqlfiddle.com中创建虚拟表的代码
CREATE TABLE users
(`user_id` int, `user_type` varchar(1))
;
insert into users VALUES (1,'A');
insert into users VALUES (2,'E');
insert into users VALUES (3,'E');
insert into users VALUES (4,'S');
insert into users VALUES (5,'S');
insert into users VALUES (6,'S');
CREATE TABLE stu_master
(`stu_master_id` int,`stu_master_stu_info_id` int,`stu_master_user_id` int)
;
insert into stu_master VALUES (1,1,4);
insert into stu_master VALUES (2,2,5);
insert into stu_master VALUES (3,3,6);
insert into stu_master VALUES (4,4,7);
insert into stu_master VALUES (5,5,8);
CREATE TABLE stu_info
(`stu_info_id` int,`stu_first_name` varchar(10),`stu_last_name` varchar(10))
;
insert into stu_info VALUES (1,'Student','One');
insert into stu_info VALUES (2,'Student','Two');
insert into stu_info VALUES (3,'Student','Three');
insert into stu_info VALUES (4,'Student','Four');
insert into stu_info VALUES (5,'Student','Five');
CREATE TABLE emp_master
(`em_id` int,`em_emp_info_id` int,`em_user_id` int)
;
insert into emp_master VALUES (1,1,2);
insert into emp_master VALUES (2,2,3);
insert into emp_master VALUES (3,3,736);
insert into emp_master VALUES (4,4,737);
insert into emp_master VALUES (5,5,738);
CREATE TABLE emp_info
(`emp_info_id` int,`emp_first_name` varchar(10),`emp_last_name` varchar(10))
;
insert into emp_info VALUES (1,'Employee','One');
insert into emp_info VALUES (2,'Employee','Two');
insert into emp_info VALUES (3,'Employee','Three');
insert into emp_info VALUES (4,'Employee','Four');
insert into emp_info VALUES (5,'Employee','Five');
答案 2 :(得分:1)
您需要比较两个联接中的条件,因为您要将用户表与左连接加入,而您的学生和员工表加入右侧。如果你不比较两个左连接中的条件,它将分别左边有两个表,然后是UNION它们。因此,您将从单一条件获得不必要的记录。
{{1}}