将SQL行显示到行数可能不同的列

时间:2016-09-09 16:13:37

标签: sql oracle pivot

我有一个表,如下所示

ID    Latest_rating
---  --------------
1      3
2      5

然后我有一个 main_audit 表格,其中显示了评分更改历史记录,如下所示

ID   rating  rating_change_date
--   ------  ------------------
1      2     26-Sep-15
1      4     16-Apr-14
1      3     10-Mar-13
2      3     04-Apr-15
2      2     01-Oct-13

所以我必须加入两个表,并应显示如下

ID  Latest_Rating  1st_Rating rating_change_date 2nd_rating rating_change_date
--  -------------  ---------- ------------------ ---------- ------------------
1         3            3          10-Mar-13          4          16-Apr-14
2         5            2          01-Oct-13          3          04-Apr-15

我应该按照上面的列显示第一评级,第二评级,第三评级,4评级

2 个答案:

答案 0 :(得分:0)

您可以使用row_number()和聚合执行此操作。棘手的部分是:

select ma.id,
       max(case when seqnum = 1 then rating end) as first_rating,
       max(case when seqnum = 1 then rating_change_date end) as first_rating_change_date,
       max(case when seqnum = 2 then ma.rating end) as second_rating,
       max(case when seqnum = 2 then ma.rating_change_date end) as second_rating_change_date
from (select ma.*,
             row_number() over (partition by id order by rating_change_date desc) as seqnum
      from main_audit ma
     ) ma
group by id;

然后你可以将它们组合起来:

with ma as (
      select ma.id,
             max(case when seqnum = 1 then rating end) as first_rating,
             max(case when seqnum = 1 then rating_change_date end) as first_rating_change_date,
             max(case when seqnum = 2 then ma.rating end) as second_rating,
             max(case when seqnum = 2 then ma.rating_change_date end) as second_rating_change_date
      from (select ma.*,
                   row_number() over (partition by id order by rating_change_date desc) as seqnum
            from main_audit ma
           ) ma
      group by id
     )
select m.id, m.latest_rating,
       ma.first_rating, ma.first_rating_change_date,
       ma.second_rating, ma.second_rating_change_date
from main m join
     ma
     on m.id = ma.id;

答案 1 :(得分:0)

根据您的评论,如果评分相同,您可以合并,如果有3个更改,则可以采用最小日期1& 2是相同的1& 2合并,第3个变化向上移动到2号。此外,不需要3个查询,您可以在1个嵌套选择中使用连接和条件聚合来执行此操作:

class Foo {
public:
    std::vector<Item*> items = { nullptr, new Item(), new Item(), nullptr };

    // function to return all non-nullptr items as an iterator
};

int main() {
    Foo foo;

    for (Item* i : foo.functionToReturnIteratorOverAllNullItems)
        // do something
}

就您对变更数量的评论而言。您可以硬编码到您认为可能存在或不存在的完整数字,如果没有那么多更改,或者您需要转向动态SQL,则字段将为空。

条件聚合而不是PIVOT的原因是因为您需要聚合多个列,如果您只想要评级或日期,那么您可以使用PIVOT并且编写的代码会少一些(http://www.oracle.com/technetwork/articles/sql/11g-pivot-097235.html