SQL ORDER BY,在列表末尾获取负值

SQL ORDER BY,在列表末尾获取负值,sql,postgresql,Sql,Postgresql,我试图找到一个按功能定制订单的解决方案 我有一个表,它可以简化为一个文本字段和一个整数类别值: text | category ---------------------- 'Item 1' | 3 'Item 2' | -1 'Item 3' | 2 'Item 4' | -1 'Item 5' | 3 'Item 6' | 1 整数值-1表示未使用该类别 我想做的是按类别排序,最后得到-1的值,例如,结果如下: text | category -------

我试图找到一个按功能定制订单的解决方案

我有一个表,它可以简化为一个文本字段和一个整数类别值:

text      | category
----------------------
'Item 1'  | 3
'Item 2'  | -1
'Item 3'  | 2
'Item 4'  | -1
'Item 5'  | 3
'Item 6'  | 1
整数值-1表示未使用该类别

我想做的是按类别排序,最后得到-1的值,例如,结果如下:

text      | category
----------------------
'Item 6'  | 1
'Item 3'  | 2
'Item 1'  | 3
'Item 5'  | 3
'Item 2'  | -1
'Item 4'  | -1
为此,我不能接触数据库中存储的数据,我希望避免存储过程

我用的是Postgres9.2

我已尝试在此处创建在线测试:

创建测试表的SQL语句:

CREATE TABLE test_order
(
text text,
category integer
);
INSERT INTO test_order values('Item 1',3);
INSERT INTO test_order values('Item 2',-1);
INSERT INTO test_order values('Item 3',2);
INSERT INTO test_order values('Item 4',-1);
INSERT INTO test_order values('Item 5',3);
INSERT INTO test_order values('Item 6',1);
按以下顺序使用多个键:

将布尔值转换为整数时,true的值为1,false的值为0。因此,order by使用desc。

其他选项使用UNION ALL

第一个选择就是按order by运算符进行排序。然后,我们将category=-1的剩余行添加到第一次选择的行中。

对于SQL Server,您可以使用以下查询:

SELECT tor.texts, tor.category
FROM #test_order AS tor
ORDER BY REPLACE(tor.category
           , -1
           , (   SELECT MAX(category) + 1
                 FROM #test_order))
  , tor.texts;

Postgres将空值视为默认值,因此这将起作用:

SELECT * 
FROM test_order 
ORDER BY NULLIF(category, -1), text;
如果要按降序排序,还支持标准SQL的NULL FIRST/LAST:

ORDER BY 
   NULLIF(category, -1) DESC NULLS LAST, text
关于DISTINCT ON,您必须在DISTINCT和ORDER中使用相同的表达式:

SELECT DISTINCT ON (text,NULLIF(category, -1)) text,category 
FROM test_order 
ORDER BY NULLIF(category, -1) NULLS LAST, text;

请参见

如果类别为-1,请为其指定最大值


这是DBA在设计数据库时应该处理的事情

这是一个非常优雅的解决方案,但当我用我的真实查询测试它时,我无法让它工作,还有一个独特的要求:选择DISTINCT ON text,category text,category FROM test_order BY category,text;添加您的魔术:选择不同的文本、类别文本、测试中的类别\u顺序按类别>=0::int desc、类别asc、文本;我得到了以下错误消息:错误:SELECT DISTINCT ON表达式必须匹配表达式的初始顺序第1行:SELECT DISTINCT ON text、category text、category FROM test_o。。。我使用的实际表有更多列。@spist\u opp。我真的建议你再问一个问题。这不是你在这里问的问题。但您的问题的答案是,您应该使用子查询—一个用于不同的on,另一个用于最终排序。工作正常,但从经验上看似乎有点慢。无法保证将按预期顺序返回行。@dnoeth,请您解释一下,这是为什么?
ORDER BY 
   NULLIF(category, -1) DESC NULLS LAST, text
SELECT DISTINCT ON (text,NULLIF(category, -1)) text,category 
FROM test_order 
ORDER BY NULLIF(category, -1) NULLS LAST, text;
SELECT
            O.text,
            O.category
    FROM
            test_order O
    ORDER BY
            CASE
                WHEN category = -1 THEN 2147483647
                ELSE category
            END,
            text;
SELECT NULLIF(category, -1) as nulled_category, * 
from test_order 
ORDER BY nulled_category ASC nulls last, text;