如何在列中按字母顺序对结果进行排序

时间:2015-09-16 13:55:57

标签: sql oracle

我有一些用户表和代码表。每个用户都有4个代码。我需要为id为5234的用户返回4个代码,但按字母顺序排序。

像这样:

SELECT 
    --results sorted alphabetically
    <here_should_be 'aaa'> code1,
    <here should be 'bbb'> code2,
    <here should be 'ccc'> code3,
    <here should be 'ddd'> code4
FROM
    user bt 
    LEFT JOIN table_with_codes value_1 ON (bt.rk_id = value_1.rk_id AND value_1.code = 'code_1') --assume value_1.string_value return 'bbb'
    LEFT JOIN table_with_codes value_2 ON (bt.rk_id = value_2.rk_id AND value_2.code = 'code_2') --assume value_2.string_value return 'aaa'
    LEFT JOIN table_with_codes value_3 ON (bt.rk_id = value_3.rk_id AND value_3.code = 'code_3') --assume value_3.string_value return 'ddd'
    LEFT JOIN table_with_codes value_4 ON (bt.rk_id = value_4.rk_id AND value_4.code = 'code_4') --assume value_4.string_value return 'ccc'
 WHERE bt.id = 5234;  

最好的方法是什么?

1 个答案:

答案 0 :(得分:1)

SQL Fiddle

在OP更新之前 - 如果4个值位于同一个表的同一行的不同列中:

Oracle 11g R2架构设置
查询1

WITH data ( z1, z2, z3, z4 ) AS (
  SELECT 'bbb', 'aaa', 'ccc', 'ddd' FROM DUAL
)
SELECT LEAST( z1, z2, z3, z4 ) c1,
       CASE WHEN z1 <= z2 AND z2 <= z3 AND z2 <= z4 THEN z2
            WHEN z1 <= z3 AND z3 <= z2 AND z3 <= z4 THEN z3
            WHEN z1 <= z4 AND z4 <= z2 AND z4 <= z3 THEN z4
            WHEN z2 <= z1 AND z1 <= z3 AND z1 <= z4 THEN z1
            WHEN z2 <= z3 AND z3 <= z1 AND z3 <= z4 THEN z3
            WHEN z2 <= z4 AND z4 <= z1 AND z4 <= z3 THEN z4
            WHEN z3 <= z1 AND z1 <= z2 AND z1 <= z4 THEN z1
            WHEN z3 <= z2 AND z2 <= z1 AND z2 <= z4 THEN z2
            WHEN z3 <= z4 AND z4 <= z1 AND z4 <= z2 THEN z4
            WHEN z4 <= z1 AND z1 <= z3 AND z1 <= z4 THEN z1
            WHEN z4 <= z2 AND z2 <= z1 AND z2 <= z3 THEN z2
            WHEN z4 <= z3 AND z3 <= z1 AND z3 <= z2 THEN z3 END AS c2,
       CASE WHEN z1 >= z2 AND z2 >= z3 AND z2 >= z4 THEN z2
            WHEN z1 >= z3 AND z3 >= z2 AND z3 >= z4 THEN z3
            WHEN z1 >= z4 AND z4 >= z2 AND z4 >= z3 THEN z4
            WHEN z2 >= z1 AND z1 >= z3 AND z1 >= z4 THEN z1
            WHEN z2 >= z3 AND z3 >= z1 AND z3 >= z4 THEN z3
            WHEN z2 >= z4 AND z4 >= z1 AND z4 >= z3 THEN z4
            WHEN z3 >= z1 AND z1 >= z2 AND z1 >= z4 THEN z1
            WHEN z3 >= z2 AND z2 >= z1 AND z2 >= z4 THEN z2
            WHEN z3 >= z4 AND z4 >= z1 AND z4 >= z2 THEN z4
            WHEN z4 >= z1 AND z1 >= z3 AND z1 >= z4 THEN z1
            WHEN z4 >= z2 AND z2 >= z1 AND z2 >= z3 THEN z2
            WHEN z4 >= z3 AND z3 >= z1 AND z3 >= z2 THEN z3 END AS c3,
       GREATEST( z1, z2, z3, z4 ) c4
FROM   data

<强> Results

|  C1 |  C2 |  C3 |  C4 |
|-----|-----|-----|-----|
| aaa | bbb | ccc | ddd |

OP更新后 - 如果4个值位于同一个表的不同行中:

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE users ( id, rk_id ) AS
SELECT 5234, 1 FROM DUAL;

CREATE TABLE table_with_codes (rk_id, code, string_value ) AS
          SELECT 1, 'code1', 'bbb' FROM DUAL
UNION ALL SELECT 1, 'code2', 'ddd' FROM DUAL
UNION ALL SELECT 1, 'code3', 'aaa' FROM DUAL
UNION ALL SELECT 1, 'code4', 'ccc' FROM DUAL;

查询2

WITH ordered_codes ( rk_id, idx, string_value ) AS (
  SELECT rk_id,
         ROW_NUMBER() OVER ( PARTITION BY rk_id ORDER BY string_value ),
         string_value
  FROM   table_with_codes
)
SELECT u.id,
       MAX( CASE idx WHEN 1 THEN string_value END ) AS c1,
       MAX( CASE idx WHEN 2 THEN string_value END ) AS c2,
       MAX( CASE idx WHEN 3 THEN string_value END ) AS c3,
       MAX( CASE idx WHEN 4 THEN string_value END ) AS c4
FROM   users u
       LEFT OUTER JOIN ordered_codes o
       ON ( u.rk_id = o.rk_id )
WHERE  u.id = 5234
GROUP BY u.id

<强> Results

|   ID |  C1 |  C2 |  C3 |  C4 |
|------|-----|-----|-----|-----|
| 5234 | aaa | bbb | ccc | ddd |