我有一个名为 users 的表包含
(Table A)
Users
user_id
username
user_type[1,2]
(Table B) if user_type=1
user_id
full_name
(Table C) if user_type=2
user_id
full_name
我想通过执行单个查询来获得单个记录集,这在 PHP mysql 中是否可行。
试试这个:
SELECT table_a.*, COALESCE(table_b.full_name,table_c.full_name) AS full_name
FROM table_a
LEFT OUTER JOIN table_b ON table_b.user_id = table_a.user_id
LEFT OUTER JOIN table_c ON table_c.user_id = table_a.user_id WHERE 1;
它使用LEFT OUTER JOIN
,这意味着它table_b
在给定条件下将其加入。但是,对于 中的每一行table_a
,无论是否在其中找到匹配的行table_b
,它都会返回该table_a
行。如果它没有找到匹配的行,则这些table_b
列只是 NULL。与table_c
.
然后,我们只需选择所有table_a
列。但是,我们现在有两full_name
列,一列来自table_b
,一列来自table_c
。我们COALESCE
用来合并它们。
COALESCE
返回第一个非NULL
值。
既然我们知道在 中要么有匹配的行,table_b
要么有匹配的行table_c
,所以这不是问题。table_b
但是,如果您以某种方式允许在和中找到匹配的行,那将是一个问题table_c
。
可以通过添加额外的ON
子句条件来减轻风险,以获得:
SELECT table_a.*, COALESCE(table_b.full_name,table_c.full_name) AS full_name
FROM table_a
LEFT OUTER JOIN table_b
ON table_b.user_id = table_a.user_id AND table_a.user_type = 1
LEFT OUTER JOIN table_c
ON table_c.user_id = table_a.user_id AND table_a.user_type = 2
WHERE 1;
尽管如此,您仍需要确保 和 中的每个用户仅存在 1table_b
行table_c
。
而不是COALESCE
你可以选择使用CASE
像:
SELECT table_a.*, CASE user_type WHEN 1
THEN table_b.full_name
ELSE table_c.full_name END AS full_name
...
或使用如下IF
函数: SELECT table_a.*, IF(user_type=1,table_b.full_name,table_c.full_name) AS full_name ...
您可以UNION
同时使用表和稍后JOIN
使用tableA
SELECT a.User_ID,
a.`username`,
b.full_name,
a.user_type
FROM tableA a
(
SELECT user_ID, full_name
FROM tableB
UNION
SELECT user_ID, full_name
FROM tableC
) b ON a.User_ID = b.User_ID
-- WHERE a.user_type = 1 -- add extra condition here