简体   繁体   English

按列值的给定“等级”排序

[英]Sort by given "rank" of column values

I have a table like this ( unsorted ):我有一个这样的表(未排序):

risk风险 category类别
Low低的 A一种
Medium中等的 B
High高的 C C
Medium中等的 A一种
Low低的 B
High高的 A一种
Low低的 C C
Low低的 E
Low低的 D
High高的 B

I need to sort rows by category , but first based on the value of risk .我需要按category对行进行排序,但首先要基于risk值。 The desired result should look like this ( sorted ):所需的结果应如下所示(已排序):

risk风险 category类别
Low低的 A一种
Low低的 B
Low低的 C C
Low低的 D
Low低的 E
Medium中等的 A一种
Medium中等的 B
High高的 A一种
High高的 B
High高的 C C

I've come up with below query but wonder if it is correct:我提出了以下查询,但想知道它是否正确:

SELECT
    *
FROM
    some_table
ORDER BY
    CASE
    WHEN risk = 'Low'    THEN
    0
    WHEN risk = 'Medium' THEN
    1
    WHEN risk = 'High'   THEN
    2
    ELSE
    3
    END,
    category;

Just want to understand whether the query is correct or not.只是想了解查询是否正确。 The actual data set is huge and there are many other values for risk and categories and hence I can't figure out if the results are correct or not.实际数据集很大,风险和类别还有很多其他值,因此我无法确定结果是否正确。 I've just simplified it here.我只是在这里简化了它。

Basically correct, but you can simplify:基本正确,但你可以简化:

SELECT *
FROM   some_table
ORDER  BY CASE risk
            WHEN 'Low'    THEN 0
            WHEN 'Medium' THEN 1
            WHEN 'High'   THEN 2
            -- rest defaults to NULL and sorts last
          END
        , category;

A "switched" CASE is shorter and slightly cheaper. “转换”的CASE更短且更便宜。 In the absence of an ELSE branch, all remaining cases default to NULL, and NULL sorts last in default ascending sort order.在没有ELSE分支的情况下,所有剩余的案例默认为 NULL,并且 NULL 按默认升序排序最后。 So you don't need to do anything extra.所以你不需要做任何额外的事情。

Many other values许多其他值

... there are many other values for risk ...还有许多其他风险值

While all other values are lumped together at the bottom of the sort order, this seems ok.虽然所有其他值都集中在排序顺序的底部,但这似乎没问题。
If all of those many values get their individual ranking, I would suggest an additional table to handle ranks of risk values.如果所有这些值都获得了各自的排名,我会建议使用额外的表格来处理风险值的排名。 Like:喜欢:

CREATE TABLE riskrank (
  risk text PRIMARY KEY
, riskrank real
);

INSERT INTO riskrank VALUES
  ('Low'   , 0)
, ('Medium', 1)
, ('High'  , 2)
-- many more?
; 

Data type real , so it's easy to squeeze in rows with fractional digits in different positions (like enum values do it internally).数据类型real ,因此很容易将小数位放在不同位置的行中(就像enum值在内部执行的那样)。

Then your query is:那么您的查询是:

SELECT s.*
FROM   some_table s
LEFT   JOIN risk_rank rr USING (risk)
ORDER  BY rr.riskrank, s.category;

LEFT JOIN , so missing entries in riskrank don't eliminate rows. LEFT JOIN ,因此riskrank中缺失的条目不会消除行。

enum ? enum

I already mentioned the data type enum .我已经提到了数据类型enum That's a possible alternative as enum values are sorted in the order they are defined (not how they are spelled).这是一个可能的替代方案,因为枚举值是按照它们定义的顺序排序的(而不是它们的拼写方式)。 They only occupy 4 bytes on disk ( real internally), are fast and enforce valid values implicitly.它们只占用磁盘上的 4 个字节(内部是real ),速度很快并且隐含地强制执行有效值。 See:看:

However , I would only even consider an enum if the sort order of your values is immutable.但是,如果您的值的排序顺序是不可变的,我什至只会考虑枚举。 Changing sort order and adding / removing allowed values is cumbersome.更改排序顺序和添加/删除允许的值很麻烦。 The manual: 手册:

Although enum types are primarily intended for static sets of values, there is support for adding new values to an existing enum type, and for renaming values (see ALTER TYPE ).尽管枚举类型主要用于 static 组值,但支持向现有枚举类型添加新值,以及重命名值(请参阅ALTER TYPE )。 Existing values cannot be removed from an enum type, nor can the sort ordering of such values be changed, short of dropping and re-creating the enum type.不能从枚举类型中删除现有值,也不能更改这些值的排序顺序,除非删除并重新创建枚举类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM