架构:

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。
我想按“parent”的名称(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

最佳答案

当前它只返回连接匹配的行
使用LEFT JOIN而不是JOIN也可以检索没有父级的行。
我想按“parent”的名称(f27)排序,但是如果一个父节点没有链接,我想把它放在排序的底部。
而不是

ORDER BY parent.data->>'f27' ASC

尝试在nulls中填充一个值,该值将在排序时被推到末尾(例如,字符串'zzz',但请根据您拥有的数据考虑一些有意义的内容):
ORDER BY coalesce(parent.data->>'f27', 'zzz') ASC

使用
ORDER BY parent.data->>'f27' ASC NULLS LAST

(谢谢,玛斯!)
最后,查询可以如下所示:
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

这里有一个演示:http://www.sqlfiddle.com/#!15/d18cc/16

关于sql - SQL可选联接和默认值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29883190/

10-12 14:22