2009-12-04 4 views
0

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

SELECT id, type, start, stop, one, two, three, four 
FROM a 
UNION ALL 
SELECT id, type, start, stop, one, two, three, four 
FROM b 
UNION ALL 
SELECT id, type, start, stop, one, two, three, four 
FROM c 
ORDER BY type ASC 

Результирующее в ...

row | id type start  stop   one two three four 
----+-------------------------------------------------------------- 
1 | 1 a  2010-01-01 2010-01-31 100 1000 1000 100 
2 | 1 a  2010-02-01 2010-12-31 100 500 500  50 
3 | 1 b  2010-01-01 2010-01-31 100 NULL NULL 100 
4 | 1 b  2010-01-01 2010-12-31 100 NULL NULL 100 
5 | 1 c  2010-01-01 2010-01-31 0  NULL NULL 100 
6 | 1 c  2010-01-01 2010-12-31 0  NULL NULL 100 

Однако, Я бы предпочел следующий результат ...

row | id type start  stop   one two three four 
----+-------------------------------------------------------------- 
1 | 1 a  2010-01-01 2010-01-31 100 1000 1000 100 
2 | 1 a  2010-02-01 2010-12-31 100 500 500  50 
4 | 1 b  2010-01-01 2010-12-31 100 NULL NULL 100 
6 | 1 c  2010-01-01 2010-12-31 0  NULL NULL 100 

То есть, исключая строку 3 и 5, так как они обмануты т o строки 4 и 6 во всех отношениях , ноостановка -колонка, а в то время как неудачный ряд, имеющий самое низкое значение в исключении stop -колонка должна быть удалена.

Как это сделать? Я что-то думать, как ...

SELECT * FROM (
    SELECT id, type, start, stop, one, two, three, four 
    FROM a 
    UNION ALL 
    SELECT id, type, start, stop, one, two, three, four 
    FROM b 
    UNION ALL 
    SELECT id, type, start, stop, one, two, three, four 
    FROM c 
    ORDER BY type ASC 
) AS types 
GROUP BY ... HAVING ??? 

мне нужны советы, пожалуйста, помогите.

(И нет, я не в состоянии изменить какие-либо условия, я должен работать в данной ситуации.)

ответ

1

Аналогичные вопросы были заданы и ответил. Например: Select uniques, and one of the doubles

И ваша ситуация еще проще (если я правильно понял ваше описание проблемы):

select id, type, start, max(stop), one, two, three, four 
    from (...) types 
    group by id, type, start, one, two, three, four 
    order by ... 

На месте (...) вы кладете выбирает из а, Ь и с. Просто оставьте вне order by статья.

Или, если вместо (id, type, start) -> (один, два, три, четыре), у вас есть (id, type, start, stop) -> (один, два, три, четыре) означает, что вы должны выбрать другие столбцы, которые соответствуют макс (стоп)), этот запрос обычно приводит к разумным планом выполнения:

select id, type, start, stop, one, two, three, four 
    from (...) types 
    where stop = (select max(stop) 
        from (...) t2 
        where t2.id = types.id 
         and t2.type = types.type 
         and t2.start = types.start) 

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

1

Это должно работать:

SELECT 
    id, 
    type, 
    start, 
    stop, 
    one, 
    two, 
    three, 
    four 
FROM 
    A T1 
LEFT OUTER JOIN A T2 ON 
    T2.id = T1.id AND 
    T2.type = T1.type AND 
    T2.start = T1.start AND 
    T2.one = T1.one AND 
    ... 
    T2.stop > T1.stop 
WHERE 
    T2.id IS NULL  -- This must be a NOT NULL column for this to work 

Это предполагает, что type - это то же значение, что и имена таблиц, как в ваших примерах. Если у вас могут быть повторяющиеся строки между таблицами, вам нужно будет сделать эту же логику, используя подзапрос того, что у вас есть, а не A. Если мое предположение верно, то просто замените каждый из трех ваших запросов UNION ALL указанным выше, изменив имена таблиц.

Идея состоит в том, что если существует строка, которая соответствует, но с более поздней датой остановки, то вы не хотите включать строку в результаты. Используя LEFT OUTER JOIN, единственный способ, которым T2.id был бы NULL, - это отсутствие такого совпадения, поэтому мы можем включить его в результирующий набор (поэтому id должен быть столбцом NOT NULL, чтобы это работало).

Поскольку вы сказали, что вы не можете изменить БД я избавлю вас, «этот дизайн отстой» выговор;)

Смежные вопросы