我正在处理的网站有3种不同类型的用户:管理员,申请人,审核人。这些组中的每一个都将具有一些需要存储的基本信息(名称,ID,电子邮件等)以及每个组独有的数据。我已经创建了一个users
表以及一个用于存储其唯一数据的特定组的表。
如果user_type
为“1”(申请人)的用户登录,我需要JOIN
到users_applicants
表来检索他们的完整记录。我尝试使用UNION
,但我的表格列有很多不同。
有没有办法根据用户的类型编写一个条件查询JOIN
到正确的表?我完全错误地采取了这种方式吗?
提前感谢您的帮助!
答案 0 :(得分:2)
嗯,最后你的桌子已经存在缺陷。为什么甚至为每种类型都有一张桌子?为什么不将所有这些字段放入users
表,或者可能是user_details
表(如果你真的想要一个非常规数据字段的额外表)?目前,您实际上是从关系角度创建了4个独立的用户表。
那么为什么类型表有代理键呢?为什么user_id
已经是(唯一的)主键?
如果你改变了,你只需要用户ID来检索你想要的数据,而你已经得到了(或者你甚至无法检索用户类型)。
答案 1 :(得分:1)
您可以通过编程方式执行此操作,也可以使用一系列CASE
和LEFT JOIN
来执行此操作。
为简单起见,我们使用表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
都会返回很少(如果你指定了一个用户ID,它们实际上会返回 nothing 非常快)。
你也可以使用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
版本的可维护性较低(除非您以编程方式生成),但应该稍微快一点。
在所有情况下,建议您在相应字段中保留更新的索引。
答案 2 :(得分:1)
相反,我会建议你重建这样的表结构。
创建表
users_types :
id
type
然后使用外键创建另一个表用户
users :
id
f_name
l_name
email
office
emp_id
dob
address
active_status
phone
users_types_id
现在,当您需要在特定用户不需要的字段中插入数据插入null时。你可以简单地根据id获取记录。同样使用左连接将为您提供用户类型的名称。