问题描述
|
好的,我有一个带有索引键和一个未索引字段的表。
我需要找到具有特定值的所有记录并返回该行。
我想知道是否可以按多个值排序。
例:
id x_field
-- -----
123 a
124 a
125 a
126 b
127 f
128 b
129 a
130 x
131 x
132 b
133 p
134 p
135 i
伪:想要像这样对结果排序,where ORDER BY x_field = \'f\',\'p\',\'i\',\'a\'
SELECT *
FROM table
WHERE id NOT IN (126)
ORDER BY x_field \'f\',\'a\'
因此结果将是:
id x_field
-- -----
127 f
133 p
134 p
135 i
123 a
124 a
125 a
129 a
语法是有效的,但是当我执行查询时,即使将其限制为1条记录,它也永远不会返回任何结果。还有另一种解决方法吗?
将x_field视为测试结果,我需要验证所有属于该条件的记录。我想按失败值,通过值对测试结果进行排序。因此,我可以先使用ORDER BY验证失败的值,然后再验证传递的值。
我不能做的:
GROUP BY,因为我需要返回特定的记录值
在x_field IN(\'f \',\'p \',\'i \',\'a \')的地方,我需要所有值,因为我正试图使用一个查询进行多个验证测试。并且x_field值不是DESC / ASC顺序
写完这个问题后,我开始认为我需要重新考虑一下,哈哈!
解决方法
...
WHERE
x_field IN (\'f\',\'p\',\'i\',\'a\') ...
ORDER BY
CASE x_field
WHEN \'f\' THEN 1
WHEN \'p\' THEN 2
WHEN \'i\' THEN 3
WHEN \'a\' THEN 4
ELSE 5 --needed only is no IN clause above. eg when = \'b\'
END,id
, 您可以将LEFT JOIN与\“ VALUES(\'f \',1),(\'p \',2),(\'a \',3),(\'i \',4)一起使用\”,然后在order-by表达式中使用第二列。如果您有很多价值,Postgres将使用哈希联接,该哈希联接比大型CASE快得多。而且更容易自动生成。
如果此订购信息是固定的,则它应该具有自己的表。
, 尝试:
ORDER BY x_field=\'F\',x_field=\'P\',x_field=\'A\',x_field=\'I\'
您处在正确的轨道上,但是通过仅将x_field放在F值上,将其他3个视为常量,而不与数据集中的任何内容进行比较。
, 使用ѭ6开关将代码转换成可以排序的数字:
ORDER BY
case x_field
when \'f\' then 1
when \'p\' then 2
when \'i\' then 3
when \'a\' then 4
else 5
end
, CASE
和ORDER BY
的建议都应该起作用,但是我要建议另一种颜色的马。假设x_field
只有合理数量的值,并且您已经知道它们的含义,请创建一个枚举类型,并以F,P,A和I作为值(以及其他适用的可能值)。枚举将按其“ 11”语句隐含的顺序排序。此外,您可以使用有意义的值名称(您的实际应用程序可能会使用,而您刚刚对其进行了屏蔽以确保机密性),而不会浪费空间,因为仅存储了序数位置。
, 我找到了一个更清洁的解决方案:
ORDER BY array_position(ARRAY[\'f\',\'a\']::varchar[],x_field)
注意:array_position需要Postgres v9.5或更高版本。
, 您可以按选定的列或其他表达式排序。
下面是一个示例,说明如何通过案例陈述的结果进行排序:
SELECT col1,col2
FROM tbl_Bill
WHERE col1 = 0
ORDER BY -- order by case-statement
CASE WHEN tbl_Bill.IsGen = 0 THEN 0
WHEN tbl_Bill.IsGen = 1 THEN 1
ELSE 2 END
结果将是一个列表,该列表以\“ IsGen = 0 \”行开头,然后是\“ IsGen = 1 \”行,而所有其他行都以结尾结尾。
您可以在末尾添加更多订单参数:
SELECT col1,col2
FROM tbl_Bill
WHERE col1 = 0
ORDER BY -- order by case-statement
CASE WHEN tbl_Bill.IsGen = 0 THEN 0
WHEN tbl_Bill.IsGen = 1 THEN 1
ELSE 2 END,col1,col2
, 您可以按顺序使用position(文本中的文本)