连接到单个列时对列值进行排序

时间:2018-11-03 10:23:20

标签: sql postgresql

如何对列值进行简单的排序 在选择中将2列或更多列连接到单个列时(似乎相关的问题很少,但不是我想要的,答案却过于复杂)?

请考虑以下情形:

具有如下表格:

    .text
    .global main
main:
    sub sp,sp,#4
    str lr,[sp,#0]

    @ compiling a recursive C procdure
    @ int fact(int n){
    @   if(n < 1){
    @       return 1;
    @   }else{
    @       return (n * fact(n-1));
    @   }
    @ }

    @ put n in r0


    mov r0,#6   
fact:   
    sub sp,sp,#8
    str lr,[sp,#8]
    str r0,[sp,#0]

    cmp r0,#1
    bge L1

    mov r0,#1
    add sp,sp,#8
    mov pc,lr


L1:
    sub r0,r0,#1
    bl fact

    mov r12,r0
    ldr r0,[sp,#0]  
    ldr lr,[sp,#0]
    add sp,sp,#8

    mul r0,r12,r0
    mov pc,lr

    mov r7,r0


    ldr r0, =format
    mov r1,r7
    bl printf

    ldr lr,[sp,#0]
    add sp,sp,#4
    mov pc,lr


    .data
format: .asciz "The Answer is %d\n"

带有数据:

DROP TABLE t1;
CREATE TABLE t1 (
    name varchar,
    name2 varchar
);

选择方式:

INSERT INTO t1 VALUES
    ('N1', 'N2')
   ,('N2', 'N1')
;

导致:

SELECT (name||name2) AS id, * from t1;

我希望后一行成为 id | name | name2 ------+------+------- N1N2 | N1 | N2 N2N1 | N2 | N1 ,而不是N1N2。所以我追求的是这样的:

N2N1

应导致:

SELECT (concat(sort(name,name2))) AS id, * from t1 ;

因此,如果 id | name | name2 ------+------+------- N1N2 | N1 | N2 N1N2 | N2 | N1 name的列值的SET相同,则name2相同。

注意:我意识到可以通过创建函数/过程来实现,但是我想知道是否还有更多的 Postgres标准方式 。这意味着我想避免安装任何扩展程序,但不要这样做,以便它也可以在Oracle或MSSQL中工作。

2 个答案:

答案 0 :(得分:2)

SELECT (least(name,name2)||greatest(name,name2)) AS id, *
FROM t1
ORDER BY 1 DESC;

答案 1 :(得分:1)

您可以使用CASE子句来决定:

demo: db<>fiddle

SELECT 
    CASE 
        WHEN name <= name2 THEN name || name2 
        ELSE name2 || name 
    END as id,
    name,
    name2
FROM t1

结果:

id     name    name2
N1N2   N1      N2
N1N2   N2      N1

如果您将拥有更多列,则更高级的排序机制可能是:将列聚合为一列(将它们聚合为一个数组,并将所有元素unnest聚合为一个公共列)。该列可以排序并汇总到您的id列中:

demo: db<>fiddle

SELECT 
    array_to_string(array_agg(all_columns ORDER BY all_columns), '') as ids,
    name, name2, name3, name4
FROM (
    SELECT 
        unnest(ARRAY[name, name2, name3, name4]) as all_columns,
        name, name2, name3, name4
    FROM t2
) s
GROUP BY name, name2, name3, name4