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;