Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Хелп по селекту  [new]
Nixic
Member

Откуда: Perm
Сообщений: 2047
Понимаю что вопрос из разряда RTFM,но
в общем вот:

Есть таблица, берем два столбца
Номер и дата
Номер записывается в столбец несколько раз, но дата в каждой записи разная.
Необходимо сделать выборку, где выбираются записи с Номером и с максимальной Датой, например:
 НОМЕР    -   ДАТА
42305810  - 01.01.2008
42305810  - 01.02.2008
42305810  - 01.03.2008
42305810  - 01.04.2008
42306978  - 23.02.2008
42306978  - 23.03.2008
42306978  - 23.04.2008
42306978  - 23.05.2008

На выходе получаем:
42305810  - 01.04.2008
42306978  - 23.05.2008

Заранее благодарен :)
25 июл 08, 11:51    [5985115]     Ответить | Цитировать Сообщить модератору
 Re: Хелп по селекту  [new]
Elic
Member

Откуда:
Сообщений: 30178
RTFM Aggregate Functions (FAQ)
25 июл 08, 11:53    [5985136]     Ответить | Цитировать Сообщить модератору
 Re: Хелп по селекту  [new]
Добрый Э - Эх
Guest
1)
select *
  from (
         select t.*, row_number() 
                           over(partition by num 
                                    order by dt desc) as rn
           from <table_name> t
       )
 where rn = 1;
 
2)
select t1.*
  from <table_name> t1
  left join <table_name> t2
    on t1.num = t2.num
   and t1.dt < t2.dt
 where t2.num is null;
 
3)
select *
  from <table_name> t1
 where (num, dt) in
       (
         select num, max(dt)
           from <table_name>
         group by num
       );
       
4)       
select t1.*
  from <table_name> t1,
       (
         select num, max(dt) as dt
           from <table_name>
          group by num
       ) v
 where t1.num = v.num
   and t1.dt = v.dt;
   
5)
select t1.*
  from <table_name> t1
 where not exists(
                   select null
                     from <table_name> t0
                    where t1.num = t0.num
                      and t1.dt < t0.dt
                 );


6)
select t1.*
  from <table_name> t1
 where dt = (
                      select max(dt)
                        from <table_name> t0
                       where t1.num = t0.num
                    )
25 июл 08, 11:57    [5985168]     Ответить | Цитировать Сообщить модератору
 Re: Хелп по селекту  [new]
Nixic
Member

Откуда: Perm
Сообщений: 2047
СПАСИБО! Добрый Э - Эх :)
прямо не ожидал такого быстрого и полного ответа :)
25 июл 08, 12:00    [5985188]     Ответить | Цитировать Сообщить модератору
 Re: Хелп по селекту  [new]
Elic
Member

Откуда:
Сообщений: 30178
Nixic
прямо не ожидал такого быстрого и полного ответа :)
То была лишь издёвка, поданная в садистской форме, над отсутствием у тебя элементарнейших знаний по SQL
25 июл 08, 12:21    [5985361]     Ответить | Цитировать Сообщить модератору
 Re: Хелп по селекту  [new]
Nixic
Member

Откуда: Perm
Сообщений: 2047
сам знаю - не надо напоминать, для меня это ПОЛНЫЙ ответ
25 июл 08, 12:38    [5985503]     Ответить | Цитировать Сообщить модератору
 Re: Хелп по селекту  [new]
_мухомор
Guest
Для этой задачи достаточно простейшего:

select num, max(dt) as dt
from <table_name>
group by num

А вот если добавить в таблицу еще один столбец, запросы Доброго Э - Эха будут очень полезны.
25 июл 08, 14:44    [5986633]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: Хелп по селекту  [new]
GERDA22
Guest
Выбор пал на такой вариант

select * from
(
select t.*,row_number() over(partition t.id,t.dt order by t.dt) rn
)
where rn =1


Хотелось бы посмотреть на использование FIRST/LAST
14 окт 09, 12:55    [7784087]     Ответить | Цитировать Сообщить модератору
 Re: Хелп по селекту  [new]
GERDA22
Guest
не в ту тему
14 окт 09, 12:56    [7784098]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: Хелп по селекту  [new]
Добрый Э - Эх
Guest
Решил дописать вариант на first/last:
0) 
select num, max(dt) keep (dense_rank first order by dt desc) as max_dt
  from <table_name> t
 group by num

1)
select *
  from (
         select t.*, row_number() 
                           over(partition by num 
                                    order by dt desc) as rn
           from <table_name> t
       )
 where rn = 1;
 
2)
select t1.*
  from <table_name> t1
  left join <table_name> t2
    on t1.num = t2.num
   and t1.dt < t2.dt
 where t2.num is null;
 
3)
select *
  from <table_name> t1
 where (num, dt) in
       (
         select num, max(dt)
           from <table_name>
         group by num
       );
       
4)       
select t1.*
  from <table_name> t1,
       (
         select num, max(dt) as dt
           from <table_name>
          group by num
       ) v
 where t1.num = v.num
   and t1.dt = v.dt;
   
5)
select t1.*
  from <table_name> t1
 where not exists(
                   select null
                     from <table_name> t0
                    where t1.num = t0.num
                      and t1.dt < t0.dt
                 );


6)
select t1.*
  from <table_name> t1
 where dt = (
                      select max(dt)
                        from <table_name> t0
                       where t1.num = t0.num
                    )
15 фев 13, 13:18    [13931438]     Ответить | Цитировать Сообщить модератору
 Re: Хелп по селекту  [new]
--Eugene--
Member

Откуда: Боярышник
Сообщений: 2188
Добрый Э - Эх,

я (да разве я один?) всё никак не могу уяснить, зачем там (в конструкции KEEP) в самом начале агрегационная функция?
вот кто бы объяснил в каком случае она будет играть роль?
15 фев 13, 17:31    [13933407]     Ответить | Цитировать Сообщить модератору
 Re: Хелп по селекту  [new]
Vint
Member

Откуда: Москва
Сообщений: 4576
--Eugene--,
читайте документацию)) да и на форуме много раз обсуждалось. в случае наличия двух записей в конце или начале списка dense_rank first\last order by ... будет выбрано то значение которое было указано в агрегатной функции. сделайте такой пример и всё станет ясно.
15 фев 13, 17:34    [13933442]     Ответить | Цитировать Сообщить модератору
 Re: Хелп по селекту  [new]
--Eugene--
Member

Откуда: Боярышник
Сообщений: 2188
Vint,

вот ведь!
про неуникальность значения, по которому происходит сортировка, я как-то не подумал
сенькс
15 фев 13, 17:37    [13933457]     Ответить | Цитировать Сообщить модератору
 Re: Хелп по селекту  [new]
Zloxa
Member

Откуда: СССР ☭
Сообщений: 1033
--Eugene--,

Это в документации описано. На случай, если критерий ранжирования указанный в order by допускает неоднозначность, под критерий first/last может попасть более одной записи, к ним и применяется аггрегат.
15 фев 13, 17:38    [13933467]     Ответить | Цитировать Сообщить модератору
 Re: Хелп по селекту  [new]
Ыщщо адын
Guest
--Eugene--
(в конструкции KEEP)

Ну нет, нет в oracle rdbms такой конструкции, не-ту...
Это ключевое слово - синтаксическая часть "конструкции" функций FIRST/LAST
15 фев 13, 17:58    [13933643]     Ответить | Цитировать Сообщить модератору
 Re: Хелп по селекту  [new]
.stax..
Guest
--Eugene--,
мне так обьясняли

https://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=163973&msg=1356765

...
stax
15 фев 13, 18:02    [13933669]     Ответить | Цитировать Сообщить модератору
 Re: Хелп по селекту  [new]
suPPLer
Member

Откуда: Харків, Україна
Сообщений: 7794
Блог
--Eugene--
зачем там (в конструкции KEEP) в самом начале агрегационная функция?
вот кто бы объяснил в каком случае она будет играть роль?


А вот в таком:

drop table dropme;
create table dropme 
as
select 1 gid, 1 scale, 1 val from dual
 union all
select 1 gid, 2 scale, 1 val from dual
 union all
select 1 gid, 3 scale, 1 val from dual
 union all
select 2 gid, 1 scale, 1 val from dual
 union all
select 2 gid, 1 scale, 3 val from dual
 union all
select 2 gid, 1 scale, 4 val from dual
/

column avg_val format 0D0999
select gid
     , min(val) keep(dense_rank first order by scale) min_val
     , max(val) keep(dense_rank first order by scale) max_val
     , avg(val) keep(dense_rank first order by scale) avg_val
     , count(val) keep(dense_rank first order by scale) cnt_val
  from dropme
 group by gid
/

table DROPME dropped.
table DROPME created.
       GID    MIN_VAL    MAX_VAL AVG_VAL    CNT_VAL
---------- ---------- ---------- ------- ----------
         1          1          1  1.0000          1 
         2          1          4  2.6667          3 
15 фев 13, 19:21    [13934093]     Ответить | Цитировать Сообщить модератору
 Re: Хелп по селекту  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10206
suPPLer
А вот в таком:


select gid
     , min(val) keep(dense_rank first order by scale,rowid) min_val
     , max(val) keep(dense_rank first order by scale,rowid) max_val
     , avg(val) keep(dense_rank first order by scale,rowid) avg_val
     , count(val) keep(dense_rank first order by scale,rowid) cnt_val
  from dropme
 group by gid
/

       GID    MIN_VAL    MAX_VAL AVG_VAL    CNT_VAL
---------- ---------- ---------- ------- ----------
         1          1          1  1.0000          1
         2          1          1  1.0000          1

SQL> 


SY.
15 фев 13, 22:48    [13934864]     Ответить | Цитировать Сообщить модератору
 Re: Хелп по селекту  [new]
suPPLer
Member

Откуда: Харків, Україна
Сообщений: 7794
Блог
SY,

обход понятен. Просто иногда этим можно пользоваться, например, в задаче "вывести количество строк для максимального показателя в рамках группы":

select gid, count(val) keep(dense_rank first order by scale desc) cnt_val from dropme;

Удобная агрегация конца шкалы.
15 фев 13, 22:56    [13934893]     Ответить | Цитировать Сообщить модератору
 Re: Хелп по селекту  [new]
ЮраУчитСКЮЛ
Guest
Нужна помощь. Задача такая же как у создателя топика, все понятно с решением этой задачи. Но у меня задача немного модифицированная. У меня первая колонка находится в Таблице1 ,а вторая колонка в ТАблице2. Таблицы связаны многое ко многому через промежуточную.

и если я воспользуюсь каким либо решение с приведенных сдесь у меня выбираются не все НОМЕРа с первой колонки ,а только те у которых сама максимальная ДАТА.

Заранее спасибо
16 фев 13, 17:02    [13936132]     Ответить | Цитировать Сообщить модератору
 Re: Хелп по селекту  [new]
suPPLer
Member

Откуда: Харків, Україна
Сообщений: 7794
Блог
ЮраУчитСКЮЛ,

покажите данные, Ваши попытки в изучении SQL и результат, к которому стремитесь. Причём, данные не виде картинок, а в виде создания таблицы и вставок или таком:

with t1 as (
  select ... from dual
   union all
  select ... from dual
   ...
)
select * from t1;
16 фев 13, 17:15    [13936151]     Ответить | Цитировать Сообщить модератору
 Re: Хелп по селекту  [new]
ЮраУчитСКЮЛ
Guest
мои таблицы:

CREATE TABLE "Race"
(
"Date" date,
"RaceId" integer NOT NULL DEFAULT nextval('"Racer_RaceId_seq"'::regclass),
"Name" character varying(20),
CONSTRAINT "RaceId_PK" PRIMARY KEY ("RaceId" )
)

CREATE TABLE "Racer"
(
"FullName" character varying(20),
"RacerId" integer NOT NULL DEFAULT nextval('"Race_RacerId_seq"'::regclass),
CONSTRAINT "RacerId_PK" PRIMARY KEY ("RacerId" )
)

CREATE TABLE "Racer_Race"
(
"RRId" serial NOT NULL,
"RaceId" serial NOT NULL,
"RacerId" serial NOT NULL,
CONSTRAINT "RRId_PK" PRIMARY KEY ("RRId" ),
CONSTRAINT "RaceId_FK" FOREIGN KEY ("RaceId")
REFERENCES "Race" ("RaceId") MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT "RacerId_FK" FOREIGN KEY ("RacerId")
REFERENCES "Racer" ("RacerId") MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
-----------------------------------------------------------------------------------------
вот что я написал:

select r2."FullName",r1."Date"
from "Race" r1,"Racer" r2,"Racer_Race" rr
where r1."RaceId" = rr."RaceId"
and rr."RacerId" = r2."RacerId"
and not exists
(select null
from "Race" r3,"Racer" r4,"Racer_Race" rr2
where r2."FullName" = r4."FullName"
and r1."Date" > r3."Date");

Но в результате я получу только Гонщиков которые участвовали в заезде с минимальной датой. Мне нужно получить всех гонщиков и самый первый их заезд.

-----------------------------------------------------------------------------------------
Данную задачу решил с помощью представлений, но мне желательно без них!!
16 фев 13, 17:32    [13936184]     Ответить | Цитировать Сообщить модератору
 Re: Хелп по селекту  [new]
suPPLer
Member

Откуда: Харків, Україна
Сообщений: 7794
Блог
ЮраУчитСКЮЛ
CREATE TABLE "Race"
(
  "Date" date,
  "RaceId" integer NOT NULL DEFAULT nextval('"Racer_RaceId_seq"'::regclass),
  "Name" character varying(20),
  CONSTRAINT "RaceId_PK" PRIMARY KEY ("RaceId" )
)

CREATE TABLE "Racer"
(
  "FullName" character varying(20),
  "RacerId" integer NOT NULL DEFAULT nextval('"Race_RacerId_seq"'::regclass),
  CONSTRAINT "RacerId_PK" PRIMARY KEY ("RacerId" )
)

CREATE TABLE "Racer_Race"
(
  "RRId" serial NOT NULL,
  "RaceId" serial NOT NULL,
  "RacerId" serial NOT NULL,
  CONSTRAINT "RRId_PK" PRIMARY KEY ("RRId" ),
  CONSTRAINT "RaceId_FK" FOREIGN KEY ("RaceId")
      REFERENCES "Race" ("RaceId") MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT "RacerId_FK" FOREIGN KEY ("RacerId")
      REFERENCES "Racer" ("RacerId") MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)

-----------------------------------------------------------------------------------------
вот что я написал:

select r2."FullName",r1."Date"
from "Race" r1,"Racer" r2,"Racer_Race" rr
where r1."RaceId" = rr."RaceId"
	and rr."RacerId" = r2."RacerId"
	and not exists
	(select null
	from "Race" r3,"Racer" r4,"Racer_Race" rr2
	where r2."FullName" = r4."FullName"
                      and r1."Date" > r3."Date");


Но в результате я получу только Гонщиков которые участвовали в заезде с минимальной датой. Мне нужно получить всех гонщиков и самый первый их заезд.


Вы разделом ошиблись. Таблицы явно создавались не в Oracle Database.

PS: Для оформления кода используется тег SRC. Про него и другие замечательные вещи Вы можете прочитать здесь.
16 фев 13, 17:37    [13936207]     Ответить | Цитировать Сообщить модератору
 Re: Хелп по селекту  [new]
ЮраУчитСКЮЛ
Guest
Таблица заездов Race

Date                 IdRace
"2011-11-11";    1;    
"2009-02-23"     ;2;  
"2013-05-04"     ;3;   
"2011-06-15"     ;4;   
"2010-08-08"     ;5;  

Таблица заездов Racer

Name                 IdRacer
Racer1                  1;    
Racer2                  2;  
Racer3                  3;   
Racer4                  4;   
Racer5                  5;

Промежуточная таблица RR

RRid         RaceId    RacerId
1;           1;           1
2;           2;           2
3;           3;           3
4;           4;           4
5;           5;           5
6;           1;           2
7;           2;           4
8;           3;           5
9;           4;           3
10;           5;           1
11;           2;           5


Необходимо получить всех гонщиков и дату первого заезда в котором они участвовали. Буду благодарен.
16 фев 13, 18:03    [13936284]     Ответить | Цитировать Сообщить модератору
 Re: Хелп по селекту  [new]
ЮраУчитСКЮЛ
Guest
результат должен быть таким:

Racer           Date
"Racer2";      "2009-02-23"
"Racer4";     "2009-02-23"
"Racer3";      "2011-06-15"
"Racer1";      "2010-08-08"
"Racer5";       "2009-02-23"


Racer это гонщик, я там выше ошибся.
16 фев 13, 18:07    [13936299]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Oracle Ответить