架构:
TABLE entry
(
entry_id serial NOT NULL,
section_id integer,
deleted integer DEFAULT 0,
grp_id integer,
data json,
last_edited bigint,
last_editor_id integer
)
列e.data
可能如下所示:{f22: 5, f251: 0}
或{f22: -1, f251: 0}
如果f22未设置或{f251: 0}
,在这种情况下我希望它默认为-1
我想按“父母”的名字排序(f27),但是如果父母没有被链接,我想把它放在排序的底部。我怎么能做到这一点?
目前它只返回连接匹配的行(如果未设置f22或者为-1,则不应该匹配)。
SELECT e.*
FROM entry AS e
JOIN entry as parent ON parent.entry_id = cast(e.data->>'f22' as integer)
WHERE e.deleted = 0 AND e.section_id = $1 AND e.grp_id = $2
ORDER BY parent.data->>'f27' ASC
我最终得到了什么:
SELECT e.*
FROM entry AS e
LEFT JOIN entry as parent ON (
parent.entry_id = cast(e.data->>'f22' as integer)
AND parent.deleted = 0
AND parent.grp_id = $2
)
WHERE e.deleted = 0 AND e.section_id = $1 AND e.grp_id = $2
ORDER BY parent.data->>'f27' ASC NULLS LAST
答案 0 :(得分:1)
目前它只返回连接匹配的行
使用LEFT JOIN
代替JOIN也可以检索不具备"的行。父母。
我想按照父母的姓名(f27)排序,但如果父母没有关联,我想把它放在底部那种。
而不是
ORDER BY parent.data->>'f27' ASC
尝试使用在排序时推送到最后的值填充 null
s(例如,字符串'zzz'
,但要考虑一些有意义的内容你有的数据):
ORDER BY coalesce(parent.data->>'f27', 'zzz') ASC
使用
ORDER BY parent.data->>'f27' ASC NULLS LAST
(谢谢,Marth!)
最后,您的查询可能如下所示:
SELECT e.*
FROM entry AS e
LEFT JOIN entry as parent
ON parent.entry_id = cast(e.data->>'f22' as integer)
WHERE e.deleted = 0 AND e.section_id = $1 AND e.grp_id = $2
ORDER BY parent.data->>'f27' ASC NULLS LAST
答案 1 :(得分:1)
除了使用left join
代替inner
之外,left join
ed表上的所有条件都必须从where
子句移到from
条款,否则您仍将处于inner join
状态。
select e.*
from
entry as e
left join
entry as p on
p.entry_id = cast(e.data->>'f22' as integer)
and e.deleted = 0
and e.section_id = $1
and e.grp_id = $2
order by p.data->>'f27' asc nulls last
如果必须全部返回parent
表格的行,请在left join
上方更改right join
。