好的我有一个带有索引键和非索引字段的表。 我需要查找具有特定值的所有记录并返回该行。 我想知道我是否可以按多个值排序。
示例:
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
pseudo:希望结果像这样排序where ORDER BY x_field = 'f', 'p', 'i', 'a'
SELECT *
FROM table
WHERE id NOT IN (126)
ORDER BY x_field 'f', 'p', 'i', '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验证传递的值。
我不能做的事情:
在写完这个问题后,我开始认为我需要重新考虑这个问题,哈哈!
答案 0 :(得分:138)
...
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
答案 1 :(得分:22)
你可以使用LEFT JOIN和“VALUES('f',1),('p',2),('a',3),('i',4)”并使用第二列在你的订单表达中。 Postgres将使用Hash Join,如果你有很多值,它将比一个巨大的CASE快得多。并且它更容易自动生成。
如果这个订购信息是固定的,那么它应该有自己的表。
答案 2 :(得分:17)
尝试:
ORDER BY x_field='F', x_field='P', x_field='A', x_field='I'
您处于正确的轨道上,但是只将x_field放在F值上,其他3个被视为常量,而不是与数据集中的任何内容进行比较。
答案 3 :(得分:11)
使用case
开关将代码转换为可以分类的数字:
ORDER BY
case x_field
when 'f' then 1
when 'p' then 2
when 'i' then 3
when 'a' then 4
else 5
end
答案 4 :(得分:6)
CASE
和ORDER BY
建议都应该有效,但我会建议一匹颜色不同的马。假设x_field
只有合理数量的值,并且您已经知道它们是什么,请创建一个{,3}},其中包含F,P,A和I作为值(加上其他任何可能适用的值) )。枚举将按其CREATE
语句隐含的顺序排序。此外,您可以使用有意义的值名称 - 您的真实应用程序可能会这样做,并且您只是为了保密而屏蔽它们 - 没有浪费的空间,因为只存储了序数位置。
答案 5 :(得分:5)
我找到了一个更清洁的解决方案:
ORDER BY array_position(ARRAY['f', 'p', 'i', 'a']::varchar[], x_field)
注意:array_position需要Postgres v9.5或更高版本。
答案 6 :(得分:0)
您可以按选定的列或其他表达式进行排序。
在此示例如何根据案例陈述的结果进行排序:
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
答案 7 :(得分:0)
对于使用 CASE 进行 ORDER BY 的人来说,这可能会有用
ORDER BY
CASE WHEN GRADE = 'A' THEN 0
WHEN GRADE = 'B' THEN 1
ELSE 2 END
答案 8 :(得分:0)
由于我没有足够的声誉来撰写评论,因此将其添加为新答案。
您可以将asc或desc添加到order by子句中。
ORDER BY x_field='A' ASC, x_field='I' DESC, x_field='P' DESC, x_field='F' ASC
这使我排在第一位,P位居第二,A位排在最后,F位排在最后。
答案 9 :(得分:0)
@bobflux的answer很棒。我想通过添加使用建议方法的完整查询来扩展它。
<mat-select name="countryString" panelClass="panel-custom-width" [(value)]="selectedCountry">
<mat-option [value]="'GB'">Great Britain</mat-option>
<mat-option [value]="'US'">United States</mat-option>
<mat-option [value]="'CA'">Canada</mat-option>
</mat-select>
这里是完整的demo。
答案 10 :(得分:-2)
您可以按顺序使用位置(文本中的文字)来排序序列