один sql (oracle) запрос для получения уникальной информации, которая имеет два разных (нулевых и не нулевых) значения на столбец - PullRequest
1 голос
/ 01 августа 2011

Таблица foobar , для ясности, структурирована и имеет следующие данные:

id, action_dt, status_id
1, '02-JUL-10', 'x'
1, '02-JUL-10', '2'
1, '02-JUL-10', NULL
2, '02-JUL-10', 'a'
2, '02-JUL-10', 'b'
3, '02-JUL-10', 'k'
3, '02-JUL-10', NULL
3, '03-JUL-10', 'k'
3, '03-JUL-10', NULL

Мне нужен запрос, который получает идентификаторы, такие, что для каждого идентификатора значение NULL и значение NOTЗначение NULL существует в день.Итак, в приведенном выше примере набора данных запрос должен возвращать:

'02-JUL-10', 1
'02-JUL-10', 3
'03-JUL-10', 3

Да, это можно сделать, используя что-то вроде:

SELECT
    nulls.action_dt
    , nulls.id 

FROM        (SELECT 
                action_dt
                , id 
            FROM        foobar 
            WHERE       status_id IS NULL
            GROUP BY    action_dt)   nulls

INNER JOIN (SELECT
                action_dt
                , id
            FROM        foobar 
            WHERE       status_id IS NOT NULL
            GROUP BY    action_dt)    non_nulls     ON nulls.action_dt = non_nulls.action_dt 
                                                        AND nulls.id = non_nulls.id



, но, как вы можете видеть, среди прочеговещи, два подзапроса и еще одна итерация для объединения ...

Запрос, над которым я работал и на который надеемся, имеет форму:

SELECT
    action_dt
    , id
FROM
    foobar
GROUP BY
    action_dt
    , id
    , CASE WHEN status_id IS NOT NULL THEN 1 ELSE 0 END
HAVING
    COUNT(prim_card_nb) > 1

, но это не такдостаточно вернуть то, что мне нужно (как вы знаете, предложение HAVING применяется к базовым данным, которые запрашиваются).Любые идеи?

После всего этого, кажется, решение будет заключаться в том, чтобы поместить вышеуказанный запрос в подзапрос и отфильтровать его таким образом, например:

SELECT
    action_dt
    , id
FROM        (SELECT
                action_dt
                , id
            FROM
                foobar
            GROUP BY
                action_dt
                , id
                , CASE WHEN status_id IS NOT NULL THEN 1 ELSE 0 END
            ) repeat_ids_per_day
GROUP BY
    action_dt
    , id
HAVING
    COUNT(id) > 1

, но я чувствую этоможет быть лучше ...

Ответы [ 2 ]

1 голос
/ 01 августа 2011

Ваша идея обоснована: в таком случае вам не нужен подзапрос, совокупность достаточна и должна быть более эффективной.Это должно работать:

SQL> SELECT action_dt, id
  2    FROM foobar
  3   GROUP BY action_dt, ID
  4  HAVING COUNT(DISTINCT CASE WHEN status_id IS NULL THEN 1 ELSE 0 END) > 1;

ACTION_DT         ID
--------- ----------
02-JUL-10          1
02-JUL-10          3
03-JUL-10          3
0 голосов
/ 01 августа 2011

Я думаю, что вы должны внести некоторые незначительные изменения в ваш первый опубликованный запрос

, как показано ниже -

SELECT
    nulls.action_dt, nulls.id 

FROM        
(SELECT 
                action_dt
                , id        
            FROM        foobar 
            WHERE       status_id IS NULL
            GROUP BY    action_dt,id
uniou all
SELECT
                action_dt
                , id
            FROM        foobar 
            WHERE       status_id IS NOT NULL
            GROUP BY    action_dt,id)  
group by action_dt, id
having count(*) >1

то, что вы опубликовали, неверно, как в базе данных oracle.. Вы не можете включать не сгруппированное имя столбца при выборе .. поэтому, пожалуйста, проверьте это .. это может быть вашей ошибкой .. и может быть, это было причиной проблемы ..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...