有多种方法可以做到这一点,但如果所有首选项都有默认值,或者您在其他地方有完整的首选项列表,我会这样做:
select
default_preferences.preference_name,
coalesce(
real_user_preferences.preference_value,
default_preferences.preference_value) as preference_value
from
(select * from user_preferences where user_id is null)
as default_preferences
left join
(select * from user_preferences where user_id = @user_id)
as real_user_preferences
on
real_user_preferences.preference_name = default_preferences.preference_name
你已经在 MySQL 和 SQL Server 上都标记了你的问题,我不知道你在寻找哪种方言。我知道 SQL Server 接受这种语法,但它可能需要对 MySQL 进行一些调整。
编辑: funkwurm 指出子查询使这可能在 MySQL 上表现不佳。如果这被证明是一个问题,则可以在没有子查询的情况下将其重写为
select
default_preferences.preference_name,
coalesce(
real_user_preferences.preference_value,
default_preferences.preference_value) as preference_value
from
user_preferences as default_preferences
left join
user_preferences as real_user_preferences
on
real_user_preferences.preference_name = default_preferences.preference_name
and real_user_preferences.user_id = @user_id
where
default_preferences.user_id is null
编辑 2:如果有没有默认值的首选项,可以将第一个版本修改为使用full join
而不是left join
,并preference_name
取自默认值或用户特定首选项,就像preference_value
. 但是,第二个版本并不那么容易修改。