3

我有一张看起来像这样的桌子

Group  Recipe    Priority
0       A         400
0       A         200
0       B         500
0       B         100
1       C         300
1       C         300
1       D         600

重要性是“组”>“优先级”>“配方”

第 0 组必须先行。在第 0 组中,优先级 500 必须先行(因为它具有更高的优先级),但为了效率,所有配方都必须先行。

排序后应该是这个样子

Group  Recipe    Priority
0       B         500
0       B         100
0       A         400
0       A         200
1       D         600
1       C         300
1       C         300

我尝试了所有不同的方式来进行“订购”,但找不到正确的方式。

感谢您的帮助

4

2 回答 2

12

问题很微妙。您不想按优先级排序,而是按给定组/食谱组合的最大优先级排序。也就是说,您希望根据此最大优先级将所有配方保持在一起。

以下是这样做的:

select t.Group, t.Recipe, t.Priority,
       max(priority) over (partition by t.group, t.recipe) as maxpriority
from tablename t
order by t.Group asc, 4 desc, t.Recipe, priority desc
于 2012-06-26T16:16:57.557 回答
2

在旧版本的 Oracle 中,在提供分析函数之前,我们会使用如下查询返回指定的结果集:

SELECT f.group
     , f.recipe
     , f.priority
  FROM foo f
  JOIN ( SELECT g.group
              , g.recipe
              , MAX(g.priority) AS max_priority 
           FROM foo g
          GROUP BY g.group, g.recipe
       ) m
    ON m.group = f.group AND m.recipe = f.recipe
 ORDER BY f.group
        , m.max_priority DESC
        , f.recipe
        , f.priority DESC

这种方法适用于其他没有分析功能的数据库,例如 MySQL。

注意:上面的查询不是 NULL 安全的,因为 JOIN 谓词将消除组或配方列具有 NULL 值的行。它可以设为 NULL 安全的,但它会使 SQL 稍微复杂一些。

SELECT f.group
     , f.recipe
     , f.priority
  FROM foo f
  JOIN ( SELECT g.group
              , g.recipe
              , MAX(g.priority) AS max_priority 
           FROM foo g
          GROUP BY g.group, g.recipe
       ) m
    ON (m.group = f.group OR COALESCE(m.group,f.group) IS NULL)
       AND (m.recipe = f.recipe OR COALESCE(m.recipe,f.recipe) IS NULL)
 ORDER BY f.group
        , m.max_priority DESC
        , f.recipe
        , f.priority DESC

使用 SELECT 列表中的相关子查询也可以获得等效结果,只是该结果集在结果集中包含一个额外的“max_priority”列。

SELECT f.group
     , f.recipe
     , f.priority
     , (SELECT MAX(g.priority)
          FROM foo g
         WHERE (g.group = f.group OR COALESCE(g.group,f.group) IS NULL)
           AND (g.recipe = f.recipe OR COALESCE(g.recipe,f.recipe) IS NULL)
       ) AS max_priority
  FROM foo f
 ORDER BY f.group
        , 4 DESC
        , f.recipe
        , f.priority DESC

(我还没有测试是否可以从 SELECT 列表中删除相关的子查询并完全移至 ORDER BY 子句。如果可行,我们将消除返回额外的列,但该查询看起来非常非常奇怪。)另一个选项(省略该额外列)是将此查询(作为内联视图)包装在另一个查询中。

SELECT e.group
     , e.recipe
     , e.priority 
  FROM (
        SELECT f.group
             , f.recipe
             , f.priority
             , (SELECT MAX(g.priority)
                  FROM foo g
                 WHERE (g.group = f.group OR COALESCE(g.group,f.group) IS NULL)
                   AND (g.recipe = f.recipe OR COALESCE(g.recipe,f.recipe) IS NULL)
                ) AS max_priority
          FROM foo f
       ) e
 ORDER BY e.group
        , e.max_priority DESC
        , e.recipe
        , e.priority DESC
于 2012-06-26T22:32:34.807 回答