在SQL中按顺序排序

时间:2015-09-20 09:17:23

标签: sql oracle sql-order-by

我有点卡在列的订单上。我从堆栈溢出中得到了另一个query的好答案,但现在只需要正确订购它。

考虑我有这些结果(无序)

|LloydA|20|
|LloydC|5 |
|LloydB|0 |
|JonesA|10|
|JonesB|0 |
|ZuberB|10|
|ZuberA|0 |

然后想要先按第二列排序它们,但也要将它排在第1列,这样结果就是

(function(){

    function drawLine(points){
        context.beginPath();
        points.forEach(function(point){
            context.lineTo(point.x, point.y);   
        });
        context.stroke();
    }

    var canvas = document.createElement('canvas');
    canvas.setAttribute('width', 500);
    canvas.setAttribute('height', 300);
    document.body.appendChild(canvas);
    context = canvas.getContext("2d");

    // top
    drawLine([{x: 100, y: 40}, {x: 400, y: 10}]);
    // bottom
    drawLine([{x: 50, y: 220}, {x: 300, y: 290}]);
    // left
    drawLine([{x: 40, y: 20}, {x: 80, y: 260}]);
    // right
    drawLine([{x: 490, y: 60}, {x: 440, y: 290}]);

})();

因为20是hte最大值,我想在顶部显示这一行,然后显示所有具有相同名称开头的行(即所有Lloyd ..)

我正在考虑订单的子选择,但我正在努力。有没有人有任何提示。

2 个答案:

答案 0 :(得分:1)

这是一个产生您需要的结果的查询:

WITH 
  -- "t" contains the raw data
  t(name, score) AS (
    SELECT 'Lloyd0', 20 FROM DUAL UNION ALL
    SELECT 'Lloyd1', 0  FROM DUAL UNION ALL
    SELECT 'Lloyd2', 5  FROM DUAL UNION ALL
    SELECT 'Jones0', 10 FROM DUAL UNION ALL
    SELECT 'Jones1', 0  FROM DUAL UNION ALL
    SELECT 'Zuber0', 0  FROM DUAL UNION ALL
    SELECT 'Zuber1', 10 FROM DUAL
  ),

  -- "u" generates the "name prefix" by removing the numbers form the names
  u(name, score, name_prefix) AS (
    SELECT name, score, regexp_replace(name, '\d+', '')
    FROM t
  ),

  -- "v" generates the max score per name_prefix ("group_rank") for each "group"
  v(name, score, group_rank, name_prefix) AS (
    SELECT name, score, MAX(score) OVER (PARTITION BY name_prefix), name_prefix
    FROM u
  )
SELECT name, score
FROM v
ORDER BY 

  -- Order by the group's rank first
  group_rank DESC, 

  -- Order equally ranked groups by name
  name_prefix ASC, 

  -- Order entries within each group by score
  score DESC

当然,您不需要为此使用公用表表达式。这可以通过派生表或视图来完成,也可以通过重复某些表达式来完成。

SQLFiddle here

注意:您的原始问题是Lloyd0而不是LloydA。它并不十分清楚"有趣的"名称的一部分确实是(例如Lloyd),以及"非有趣的"部分是(例如A0)。但我怀疑这对答案来说并不重要。

答案 1 :(得分:1)

根据您的previous SO question,您无需提取名称,只需添加GROUP MAX:

-- copied from the accepted answer
select p.* from people p  
join (select p1.first_name, p1.last_name 
      from people p1 where p1.id = 17
     )un
  on un.first_name = p.first_name 
where p.last_name like un.last_name || '%'
-- ADDED
order by  -- find the MAX for each name
   max(col2) over (partition by un.last_name),
   last_name