【问题标题】:How do I select a row based on a priority value in another row?如何根据另一行中的优先级值选择一行?
【发布时间】:2013-02-21 12:56:18
【问题描述】:

我正在使用 Oracle 11G,并且我有一个包含以下列和值的表,我想根据优先级列选择每一列的值。我只希望每个 ID 有一行。

ID    NAME   NAME_PRIORITY   COLOR   COLOR_PRIORITY
1     SAM       2             RED          1
1     SAM       2             GREEN        2
1     JOHN      1             BLUE         3
2     MARY      2             ORANGE       1
3     JON       2             RED          2
3     PETE      3             GREEN        1

期望的结果

ID   NAME    NAME_PRIORITY   COLOR     COLOR_PRIORITY
1    JOHN       1             RED           1
2    MARY       2             ORANGE        1
3    JON        2             GREEN         1

如何选择 NAME 和 COLOR 具有最低 PRIORITY # 并且每个 ID 只有一行。

【问题讨论】:

    标签: sql oracle oracle11g


    【解决方案1】:

    一个选项是:

    select d.id, min(name) keep (dense_rank first order by name_priority) name,
           min(name_priority) name_priority,
           min(color) keep (dense_rank first order by color_priority) color,
           min(color_priority) color_priority
      from yourtab d
     group by id;
    

    【讨论】:

    • +1 这很漂亮,我不知道keep。这是一个演示——sqlfiddle.com/#!4/ab996/5
    • 谢谢我从来不知道keep!我打算尝试一些更复杂的东西,比如下面的答案。这要简单得多,谢谢!
    【解决方案2】:

    您可以在name_prioritycolor_priority 上使用row_number() 来获得结果:

    select n.id,
      name, 
      name_priority,
      color,
      color_priority
    from
    (
      select id,
        name, 
        name_priority,
        row_number() over(partition by id order by name_priority) name_row
      from yourtable
    ) n
    inner join
    (
      select id,
        color, 
        color_priority,
        row_number() over(partition by id order by color_priority) color_row
      from yourtable
    ) c
      on n.id = c.id
      and n.name_row = c.color_row
    where n.name_row = 1
      and c.color_row = 1
    

    SQL Fiddle with Demo

    一旦您拥有每个优先级的row_number(),那么您将加入id 和行号上的结果,并且只返回行号等于1 的行。

    【讨论】:

      【解决方案3】:

      此查询使用Common Table ExpressionROW_NUMBER()

      WITH nameList
      AS
      (
          SELECT  ID, Name,
                  ROW_NUMBER() OVER (PARTITION BY ID 
                                  ORDER BY NAME_PRIORITY) rn
          FROM    TableName
      ),
      colorList
      AS
      (
          SELECT  a.ID, a.Name,
                  b.Color, b.COLOR_PRIORITY,
                  ROW_NUMBER() OVER (PARTITION BY a.ID 
                                  ORDER BY COLOR_PRIORITY) rnB
          FROM    nameList a
                  INNER JOIN tableName b
                      ON a.ID = b.ID AND a.rn = 1
      )
      SELECT  ID, Name, Color, COLOR_PRIORITY
      FROM    colorList
      WHERE   rnB = 1
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-05-01
        • 1970-01-01
        • 2021-07-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多