2011-02-10 5 views
2

В моей таблице у меня есть два поля, среди прочего: article_id и versionSQL, проблема с OrderBy/GroupBy

Пример:

article_id | version 
    -----------|---------- 
     5  | 1 
     5  | 2 
     6  | 1 

То, что я хочу сделать, это получить последнюю версию для каждого номер статьи. (В моем примере я хочу получить объект статьи 5 версии 2 и статью 6 и объект версии 1).

Проблема заключается в том, что mysql делает group by вместо order by, поэтому он возвращает мне ПЕРВЫЙ вариант каждой статьи, но я хочу обратное.

У вас есть идея, пожалуйста?

Решение

select * 
from article r 
where r.version=(
select max(version) 
from article r2 
where r2.article_id = r.article_id 
); 
+0

SELECT * FROM RESSOURCES ORDER BY версия DESC GROUP BY article_id –

ответ

5

Ваш вопрос немного расплывчато , но я считаю, это более или менее это то, что вы хотите:

 
select * from (
    select 
     <table>.*, 
     row_number() over (partition by article_id order by version desc) r 
    from 
     <table> 
) 
where r = 1 

Запрос возвращает одну запись для каждого (отдельного) article_id. Эта запись является самой высокой версией для возвращаемого article_id.

Таким образом, вместе с "теста", это можно увидеть в действии:

create table tq84_resorces (
    id   number primary key, 
    article_id number not null, 
    version  number not null 
); 

insert into tq84_resorces values (50, 5, 1); 
insert into tq84_resorces values (60, 5, 2); 
insert into tq84_resorces values (70, 6, 1); 


select * from (
    select 
     tq84_resorces.*, 
     row_number() over (partition by article_id order by version desc) r 
    from 
     tq84_resorces 
) 
where r = 1 

, который возвращает:

 ID ARTICLE_ID VERSION   R 
---------- ---------- ---------- ---------- 
     60   5   2   1 
     70   6   1   1 
+0

Хорошо, я никогда не видел такой синтаксис :). В любом случае, я нашел достойное решение (см. Мое редактирование.) Спасибо за помощь;) –

+0

Спасибо за тест! на самом деле это работает очень хорошо :-) –

+0

@Tristan: Метод row_number() - это единственный способ, которым вы должны подходить к этому. Методы самосоединения могут распространяться в других базах данных, но в Oracle это не очень хорошее решение. Аналитические функции намного быстрее и даже намного проще, когда вы привыкаете к ним. –

2
select yt.id, yt.article_id, yt.version 
    from (select article_id, max(version) as max_version 
       from YourTable 
       group by article_id) t 
     inner join YourTable yt 
      on t.article_id = yt.article_id 
       and t.max_version = yt.version 
+0

It возвращает мне неверный идентификатор, но правильный article_id и версию –

+0

@Tristan: Отредактировал мой ответ. –

+0

Спасибо, он работает намного лучше :-) –

2
select 
    article_id, 
    max(version) as Version 

from article 

group by article_id 
+0

Он возвращает мне неправильный идентификатор, но правильный article_id и версию –

+0

Что значит «неправильный идентификатор, но правильный article_id и версия»? –

+0

он возвращает: id: 5 (плохо)/article_id: 5 (хорошо)/версия: 2 (хорошо) –

1

Во-первых, вы должны изменить столбец версии в целое число (возможно, с колонной приставкой, если сильно нужно строки), чем вы можете

Select MAX(version) 
... 
Group By article_id 
1

Будет ли эта работа:

select articleId, (select top 1 version 
        from article ar2 
        where ar2.articleId = ar.articleId 
        order by version desc) as version 
from article ar 
group by ar.articlId 

Работает в SQL Server 2005, не тестировался в mysql.

+0

ergh, он должен быть совместим с Oracle, я полностью забыл об этом. и Top не соответствует требованиям оракула: o –

+0

Извините, пропустил часть оракула. – Haeflinger

+0

my bad, я отметил его как mysql :) –