SQL可选的连接和默认值

时间:2015-04-26 20:34:21

标签: sql postgresql

架构:

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

2 个答案:

答案 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

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

答案 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