假设我有一个包含以下列的成员资格表:
id, first, last, email, type, expires, parentid
其中type可以是“parent”或“child”
如果我查询的是一个孩子的身份证,我该如何返回子信息的名称和父母的过期/姓名?
基本上是这样的:
select
first,
last,
email,
if (type = "child"
select
expires,
first as parent_first,
last as parent_last
from members
where id = parentid)
else ( expires )
from members where id = 100
答案 0 :(得分:2)
不要从基于type = 'child'
动态构建SQL的角度来处理它。相反,SQL在相关集合上运行,因此解决方案实际上是针对自身LEFT JOIN
表,以便始终返回父表(尽管有时可能为空)。
虽然可以使用带有子选择的CASE
来单独交替返回父级或子级expires
,但由于您还需要父级的名称列,因此解决方案是总是返回它们,即使它们可能是NULL
。
SELECT
c.first AS first,
c.last AS last,
c.email AS email,
c.expires AS expires,
/* parent fields will be NULL if child parentid is NULL */
p.first AS parent_first,
p.last AS parent_last,
p.expires AS parent_expires
FROM
members c
/* join against the same table matching
parentid of the child to id of the parent */
LEFT JOIN members p ON c.parentid = p.id
WHERE
c.id = 100
使用LEFT JOIN
- 因此,如果子项没有parentid
的值,则父列将返回NULL。如果您只想要返回expires
的一个值,则可以使用COALESCE()
来优先选择父级,如果父级为空,则返回子级:
SELECT
...
COALESCE(p.expires, c.expires) AS expires,
或者使用CASE
并检查孩子type
(虽然COALESCE()
更好):
SELECT
...
CASE WHEN c.type = 'child' THEN p.expires ELSE c.expires END AS expires