您可以以编程方式执行此操作,也可以使用一系列CASE
s 和LEFT JOIN
s 执行此操作。
为简单起见,让我们使用一个表来执行此操作users
,您可以在其中拥有类型 1(普通用户)、2(高级用户)或 3(管理员)的用户。普通用户有一个电子邮件但没有电话,高级用户有一个地址和一个称为“超级大国”的字段,管理员只有一个电话号码,没有别的。
由于您想SELECT
对所有人都使用相同的内容,因此您当然需要将所有这些放在您的SELECT
:
SELECT user.id, user.type, email, address, superpower, telephone
然后你需要LEFT JOIN
恢复这些
FROM user
LEFT JOIN users_data ON (user.id = users_data.user_id)
LEFT JOIN power_data ON (user.id = power_data.user_id)
LEFT JOIN admin_info ON (user.id = admin_info.user_id)
现在“未使用”字段将为NULL
,但您可以提供默认值:
SELECT
CASE WHEN user.type = 0 THEN email ELSE 'nobody@nowhere.com' END AS email,
CASE WHEN user.type = 1 OR user.type = 2 THEN ... ELSE ... END as whatever,
...
您可以自行设置特定WHERE
条件JOIN
,例如,如果您只想要 J 部门的管理员,您可以使用
LEFT JOIN admin_info ON (user.id = admin_info.user_id AND admin_info.sector = 'J')
总查询时间应该不会太长,因为大多数JOIN
s 将返回很少(并且,如果您指定用户 ID,它们实际上不会很快返回任何内容)。
你也可以使用 a 来做同样的事情UNION
,这会更快:
SELECT user.id, 'default' AS email, 'othermissingfield' AS missingfieldinthistable,
... FROM user JOIN user_data ON (user.id = user_data.user_id)
WHERE ...
UNION
SELECT user.id, email, 'othermissingfield' AS missingfieldinthistable,
... FROM user JOIN power_data ON (user.id = power_data.user_id)
WHERE ...
UNION
...
现在,如果您指定用户 ID,除一个之外的所有查询都将很快失败。每个查询都具有相同的WHERE
重复条件以及任何特定于表的条件。该UNION
版本的可维护性较差(除非您以编程方式生成它),但应该稍微快一些。
在所有情况下,建议您在适当的字段上保持更新的索引。