请参考下面的SQL查询。我正在尝试创建一个简单的活动供稿,该供稿将与任务表中的updated_by
和/或created_by
字段(以较新者为准)中记录的人员匹配,并在用户中显示其个人资料图片表。这个查询有效,但是当两个字段具有不同的用户时我得到重复,因为在ON子句中,OR语句的两个元素都将返回true,因为总有一个created_by
将匹配users表中的某个人 - 我不能弄清楚当两个字段都填充不同的用户时,如何将其限制为一个。我已经尝试向ON子句添加更多CASE WHEN,但是没有if / else逻辑,所以它只是默认为两次都是true并返回相同的结果。
(注意,我需要保持在WHERE子句中限制结果的能力,其中状态项作为变量传入,查询包含在PHP函数中。)
想法?
SELECT tasks.*, users.profile_pic,
CASE WHEN tasks.updated_at > tasks.created_at
THEN tasks.updated_at
ELSE tasks.created_at
END AS recent_activity
FROM tasks
INNER JOIN users
ON tasks.updated_by = users.name OR tasks.created_by = users.name
WHERE status <> :status1 AND status <> :status2
ORDER BY recent_activity DESC LIMIT 10'
答案 0 :(得分:1)
您可以使用OR和AND模拟许多“if”逻辑,如下所示:
ON (tasks.updated_at > tasks.created_at AND tasks.updated_by = users.name)
OR (tasks.updated_at <= tasks.created_at AND tasks.created_by = users.name)
或使用类似于select中的逻辑:
ON CASE
WHEN tasks.updated_at > tasks.created_at
THEN tasks.updated_by
ELSE tasks.created_by
END = users.name
或者(因为OR和更复杂的比较,比如上面几乎排除了索引的任何好处),你可以加入users表两次并在select中选择优先级值:
SELECT tasks.*
, CASE WHEN tasks.updated_at > tasks.created_at
THEN uu.profile_pic
ELSE cu.profile_pic
END AS recent_profile_pic
, CASE WHEN tasks.updated_at > tasks.created_at
THEN uu.name
ELSE cu.name
END AS recent_activity
FROM tasks
LEFT JOIN users AS uu ON tasks.updated_by = uu.name
INNER JOIN users AS cu ON tasks.created_by = cu.name
WHERE status <> :status1 AND status <> :status2
ORDER BY recent_activity DESC LIMIT 10
这假设您使用的所有字段都没有指定它们所属的表格来自tasks
,额外的连接不会导致含糊不清。