SQL用于对每行中的列进行排序,并根据此行对行进行排序

时间:2013-09-10 12:44:03

标签: sql sqlite sorting select

我可以使用哪种SQL select查询对每行进行排序,然后对排序的行进行排序?

例如:表格标签(c1,c2,c3,c4)

2,5,8,4
2,1,6,7
5,2,9,3

查询必须提供:

1,2,6,7
2,3,5,9
2,4,5,8

4 个答案:

答案 0 :(得分:2)

SELECT
MIN(c1, c2, c3, c4) AS new_c1,
CASE MIN(c1, c2, c3, c4) WHEN c1 THEN MIN(c2, c3, c4)
                         WHEN c2 THEN MIN(c1, c3, c4)
                         WHEN c3 THEN MIN(c1, c2, c4)
                         WHEN c4 THEN MIN(c1, c2, c3)
                         END AS new_c2,
CASE MAX(c1, c2, c3, c4) WHEN c1 THEN MAX(c2, c3, c4)
                         WHEN c2 THEN MAX(c1, c3, c4)
                         WHEN c3 THEN MAX(c1, c2, c4)
                         WHEN c4 THEN MAX(c1, c2, c3)
                         END AS new_c3,
MAX(c1, c2, c3, c4) AS new_c4
FROM tab
ORDER BY new_c1, new_c2, new_c3, new_c4
  • 看到它在sqlfiddle
  • 中工作
  • 请参阅min()了解max()和{{1}}函数

引用:

  

请注意,max()[和min()]是一个简单函数,当它有2个或更多参数时,如果只给出一个参数,则作为聚合函数运行。

答案 1 :(得分:1)

这一切都是开始的,也许不是最“干净”的代码,但它会起作用

SELECT CASE WHEN C1 < C2 THEN 
                CASE WHEN C1 < C3 THEN C1 ELSE C3 END
            ELSE
                CASE WHEN C2 < C3 THEN C2 ELSE C3 END
       END

From YourTable

这将首先选择最小的元素。 还有三个,你很高兴.. 获得此结果集后,您可以按第一列排序。

答案 2 :(得分:1)

可能的解决方案:

CREATE TEMPORARY TABLE nums2
(
   Row int,
   V int
);

INSERT INTO nums2
SELECT *     
FROM
(
    SELECT rowid Row, c1 V FROM nums
    UNION ALL
    SELECT rowid Row, c2 V FROM nums
    UNION ALL
    SELECT rowid Row, c3 V FROM nums
    UNION ALL
    SELECT rowid Row, c4 V FROM nums
) 
ORDER BY Row, V;

SELECT n1.V v1, n2.V v2, n3.V v3, n4.V v4
    FROM nums2 n1
    INNER JOIN nums2 n2 ON n1.Row = n2.Row AND n2.rowid = n1.rowid + 1
    INNER JOIN nums2 n3 ON n1.Row = n3.Row AND n3.rowid = n1.rowid + 2
    INNER JOIN nums2 n4 ON n1.Row = n4.Row AND n4.rowid = n1.rowid + 3
    WHERE ((n1.rowid - 1) % 4 = 0)
    ORDER BY n1.V, n2.V, n3.V, n4.V

它使用临时表(nums2)来保存“线性化”行,使用隐藏列rowid然后将行分组回来。

测试员:http://sqlfiddle.com/#!7/d0232/38

最后一个选择可以简化一点:

SELECT n1.V v1, n2.V v2, n3.V v3, n4.V v4
    FROM nums2 n1
    INNER JOIN nums2 n2 ON n2.rowid = n1.rowid + 1
    INNER JOIN nums2 n3 ON n3.rowid = n1.rowid + 2
    INNER JOIN nums2 n4 ON n4.rowid = n1.rowid + 3
    WHERE ((n1.rowid - 1) % 4 = 0)
    ORDER BY n1.V, n2.V, n3.V, n4.V

因为WHERE表达式将“选择”每行的最低值。

测试员:http://sqlfiddle.com/#!7/d0232/39

查询很容易扩展。

答案 3 :(得分:0)

您可以将表格转换为(row_nr, col_nr, value)格式。然后您可以对其进行排序,并将其取消回原为(row_nr, val1, val2, val3, val4)格式。

; with  with_numbers as 
        (
        select  row_number() over (order by c1) rn
        ,       *
        from    tab
        )
,       normalized(rn, nr) as 
        (
        select  rn, c1 from with_numbers
        union all
        select  rn, c2 from with_numbers
        union all
        select  rn, c3 from with_numbers
        union all
        select  rn, c4 from with_numbers
        )
,       normalized_with_number as
        (
        select  row_number() over (partition by rn order by nr) rn2
        ,       *
        from    normalized
        )
,       sorted as
        (
        select  max(case when rn2 = 1 then nr end) c1
        ,       max(case when rn2 = 2 then nr end) c2
        ,       max(case when rn2 = 3 then nr end) c3
        ,       max(case when rn2 = 4 then nr end) c4
        from    normalized_with_number
        group by
                rn      
        )
select  *
from    sorted
order by
        c1
,       c2
,       c3
,       c4

See it working at SQL Fiddle.