Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Помогите пожалуйста с запросом  [new]
dick_advokat
Guest
Здравствуйте!
Допустим существует следующая таблица (результат некого реального селекта):
--------------------------------------------------------------------------------
WITH t AS
     (SELECT NULL code, NULL dat FROM DUAL UNION ALL
      SELECT '99', TO_DATE ('01.05.2010', 'DD.MM.YYYY') FROM DUAL UNION ALL
      SELECT '99', TO_DATE ('15.05.2010', 'DD.MM.YYYY') FROM DUAL UNION ALL
      SELECT '1',  TO_DATE ('16.05.2010', 'DD.MM.YYYY') FROM DUAL UNION ALL
      SELECT '1',  TO_DATE ('02.05.2010', 'DD.MM.YYYY') FROM DUAL UNION ALL
      SELECT '2',  TO_DATE ('18.05.2010', 'DD.MM.YYYY') FROM DUAL UNION ALL
      SELECT '2',  TO_DATE ('01.05.2010', 'DD.MM.YYYY') FROM DUAL UNION ALL
      SELECT '2',  TO_DATE ('20.05.2010', 'DD.MM.YYYY') FROM DUAL UNION ALL
      SELECT '88', TO_DATE ('20.05.2010', 'DD.MM.YYYY') FROM DUAL UNION ALL
      SELECT '88', TO_DATE ('17.05.2010', 'DD.MM.YYYY') FROM DUAL UNION ALL
      SELECT '3',  TO_DATE ('16.05.2010', 'DD.MM.YYYY') FROM DUAL UNION ALL
      SELECT '3',  TO_DATE ('25.05.2010', 'DD.MM.YYYY') FROM DUAL)
--------------------------------------------------------------------------------
SELECT * FROM t;
--------------------------------------------------------------------------------
Необходимо в одном запросе (вместо "SELECT * FROM t"), желательно без использования вложенных селектов, определить следующее:
1) Количество записей с кодом 1, у которых дата больше, чем максимальная дата с кодом 99 (1 запись);
2) Количество записей с кодом 2, у которых дата больше, чем максимальная дата с кодом 99 (2 записи);
3) Количество записей с кодом 3, у которых дата больше, чем максимальная дата с кодом 88 (1 запись).

Т.е. в результате получаем следующее:
| Cnt_1 | Cnt_2 | Cnt_3 |
|   1   |   2   |   1   |
и заносим эти три значения в переменные.

Заранее благодарю за ответ.
2 июн 10, 15:05    [8877916]     Ответить | Цитировать Сообщить модератору
 Re: Помогите пожалуйста с запросом  [new]
env
Member

Откуда: Россия, Москва
Сообщений: 6729
dick_advokat,

case + group by
2 июн 10, 15:08    [8877945]     Ответить | Цитировать Сообщить модератору
 Re: Помогите пожалуйста с запросом  [new]
Andrey.L
Member

Откуда: Харьков
Сообщений: 1546
env,

Первое приближение
SELECT count(case
               when code = 1 and dat > (select max(dat) from t where code=99)
               then 1
             end) as cnt_1,
       count(case
               when code = 2 and dat > (select max(dat) from t where code=99)
               then 1
             end) as cnt_2,
       count(case
               when code = 3 and dat >  (select max(dat) from t where code=88)
               then 1
             end) as cnt_3
FROM t;
2 июн 10, 15:17    [8878028]     Ответить | Цитировать Сообщить модератору
 Re: Помогите пожалуйста с запросом  [new]
Добрый Э - Эх
Guest
WITH t AS
     (SELECT NULL code, NULL dat FROM DUAL UNION ALL
      SELECT '99', TO_DATE ('01.05.2010', 'DD.MM.YYYY') FROM DUAL UNION ALL
      SELECT '99', TO_DATE ('15.05.2010', 'DD.MM.YYYY') FROM DUAL UNION ALL
      SELECT '1',  TO_DATE ('16.05.2010', 'DD.MM.YYYY') FROM DUAL UNION ALL
      SELECT '1',  TO_DATE ('02.05.2010', 'DD.MM.YYYY') FROM DUAL UNION ALL
      SELECT '2',  TO_DATE ('18.05.2010', 'DD.MM.YYYY') FROM DUAL UNION ALL
      SELECT '2',  TO_DATE ('01.05.2010', 'DD.MM.YYYY') FROM DUAL UNION ALL
      SELECT '2',  TO_DATE ('20.05.2010', 'DD.MM.YYYY') FROM DUAL UNION ALL
      SELECT '88', TO_DATE ('20.05.2010', 'DD.MM.YYYY') FROM DUAL UNION ALL
      SELECT '88', TO_DATE ('17.05.2010', 'DD.MM.YYYY') FROM DUAL UNION ALL
      SELECT '3',  TO_DATE ('16.05.2010', 'DD.MM.YYYY') FROM DUAL UNION ALL
      SELECT '3',  TO_DATE ('25.05.2010', 'DD.MM.YYYY') FROM DUAL)
--------------------------------------------------------------------------------
select count(decode(code,1,code)) as cnt_1,
       count(decode(code,2,code)) as cnt_2,
       count(decode(code,3,code)) as cnt_3
  from (
         SELECT code, dat, 
                max(decode(code,99,dat)) over() as max_dat_99,
                max(decode(code,88,dat)) over() as max_dat_88
           FROM t
       )
 where case 
          when code in (1,2) and dat > max_dat_99
               or
               code = 3 and dat > max_dat_88 then 1
       end = 1

Query finished, retrieving results...

CNT_1   CNT_2   CNT_3
-----   -----   -----
    1       2       1

1 row(s) retrieved
2 июн 10, 15:18    [8878051]     Ответить | Цитировать Сообщить модератору
 Re: Помогите пожалуйста с запросом  [new]
dick_advokat
Guest
Спасибо большое!
Добрый Э - Эх пока получает первое место :)
Еще будут варианты?
2 июн 10, 17:00    [8879293]     Ответить | Цитировать Сообщить модератору
 Re: Помогите пожалуйста с запросом  [new]
AlexFF__|
Member

Откуда:
Сообщений: 2855
dick_advokat
Спасибо большое!
Добрый Э - Эх пока получает первое место :)
Еще будут варианты?


анекдоты принимаются?
2 июн 10, 17:07    [8879368]     Ответить | Цитировать Сообщить модератору
 Re: Помогите пожалуйста с запросом  [new]
env
Member

Откуда: Россия, Москва
Сообщений: 6729
Т.е. удочка вам не пригодилась? Печально.
2 июн 10, 17:08    [8879389]     Ответить | Цитировать Сообщить модератору
 Re: Помогите пожалуйста с запросом  [new]
Elic
Member

Откуда:
Сообщений: 29990
dick_advokat
без использования вложенных селектов
select c1, c2, c3 from t
  model 
    return updated rows
    dimension by (code, dat)
    measures (dat dt, 0 c1, 0 c2, 0 c3)
    rules sequential order
    ( dt['x', date '0001-01-01'] = max (dt)['99', any]
    , c1['x', date '0001-01-01'] = count(*)[ '1', dat > dt['x', date '0001-01-01']]
    , c2['x', date '0001-01-01'] = count(*)[ '2', dat > dt['x', date '0001-01-01']]
    , dt['x', date '0001-01-01'] = max (dt)['88', any]
    , c3['x', date '0001-01-01'] = count(*)[ '3', dat > dt['x', date '0001-01-01']]
    )
;

           C1            C2            C3
------------- ------------- -------------
            1             2             1
2 июн 10, 17:36    [8879732]     Ответить | Цитировать Сообщить модератору
 Re: Помогите пожалуйста с запросом  [new]
dick_advokat
Guest
env, Вы бы продемонстрировали пример (если не трудно).
Elic, спасибо. Действительно, без использования вложенных запросов.
3 июн 10, 02:01    [8881664]     Ответить | Цитировать Сообщить модератору
 Re: Помогите пожалуйста с запросом  [new]
dick_advokat
Guest
Кстати, есть у кого-нибудь русская документация по SQL Model Clause. Она же вроде только в десятке появилась?
3 июн 10, 02:04    [8881669]     Ответить | Цитировать Сообщить модератору
 Re: Помогите пожалуйста с запросом  [new]
comphead
Member

Откуда: Киев
Сообщений: 3390
dick_advokat,

у всех есть. и в инете есть в большом кол-ве.
MODEL таки сложен в сопровождении. и не совсем обкатан на больших схемах.

вам дали очень реальные поступательные движения от господина env. не очень хорошо, что вы воспринимаете только готовые запросы.
3 июн 10, 02:50    [8881700]     Ответить | Цитировать Сообщить модератору
 Re: Помогите пожалуйста с запросом  [new]
dick_advokat
Guest
comphead, я уже целый день бьюсь над CASE+GROUP BY, но пока ничего не получается.
А господина env я попросил дать пример, чтоб было на что опираться.
Извините, такие у меня проблемы с GROUP BY.
Если это не сложно, дайте помогите с CASE+GROUP BY применительно к примеру.
3 июн 10, 03:34    [8881728]     Ответить | Цитировать Сообщить модератору
 Re: Помогите пожалуйста с запросом  [new]
comphead
Member

Откуда: Киев
Сообщений: 3390
dick_advokat,

полностью код писать не буду. рисую на пальцах, если и тогда непонятно, то извините. переквалифицируйтесь в управдомы.

select count(case when code = 1 then 1 else null) code_1,
         count(case when code = 2 then 1 else null) code_2

from t
group by code
3 июн 10, 23:27    [8888765]     Ответить | Цитировать Сообщить модератору
 Re: Помогите пожалуйста с запросом  [new]
JaRo
Member

Откуда:
Сообщений: 1659
comphead
полностью код писать не буду. рисую на пальцах, если и тогда непонятно, то извините. переквалифицируйтесь в управдомы.
Даже интересно, и что Вы имеете ввиду применительно к примеру (исключая приведенные варианты)?
4 июн 10, 10:39    [8890179]     Ответить | Цитировать Сообщить модератору
 Re: Помогите пожалуйста с запросом  [new]
Savelyev Vladimir
Member

Откуда: Оренбург
Сообщений: 200
Elic
dick_advokat
без использования вложенных селектов
select c1, c2, c3 from t
  model 
    return updated rows
    dimension by (code, dat)
    measures (dat dt, 0 c1, 0 c2, 0 c3)
    rules sequential order
    ( dt['x', date '0001-01-01'] = max (dt)['99', any]
    , c1['x', date '0001-01-01'] = count(*)[ '1', dat > dt['x', date '0001-01-01']]
    , c2['x', date '0001-01-01'] = count(*)[ '2', dat > dt['x', date '0001-01-01']]
    , dt['x', date '0001-01-01'] = max (dt)['88', any]
    , c3['x', date '0001-01-01'] = count(*)[ '3', dat > dt['x', date '0001-01-01']]
    )
;

           C1            C2            C3
------------- ------------- -------------
            1             2             1


читал про модели но сам еще не применял, хотя видел в не которых задачах данный подход был верен.

а автору следует пойти по совету с аналитическими функциями.
при таких проблемах c GROUP BY, я бы за модели не брался.
4 июн 10, 10:46    [8890236]     Ответить | Цитировать Сообщить модератору
 Re: Помогите пожалуйста с запросом  [new]
Savelyev Vladimir
Member

Откуда: Оренбург
Сообщений: 200
автору по моделям для начала
4 июн 10, 10:48    [8890262]     Ответить | Цитировать Сообщить модератору
 Re: Помогите пожалуйста с запросом  [new]
Elic
Member

Откуда:
Сообщений: 29990
Savelyev Vladimir
читал про модели но сам еще не применял, хотя видел в не которых задачах данный подход был верен.
Здесь случилась задачка, на которой можно продемонстрировать возможности "чистой" модели без итераций и перенумерации на "разреженных" данных.
Savelyev Vladimir
а автору следует
Зачастую мы пишем не только (даже скорее не столько) для авторов тем, а для закрепления пройденного, а также для формирования дидактического материала :) Т.е. для всех :)
4 июн 10, 11:00    [8890392]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить