Как получить уникальный набор строк из SQL, где уникальность определяется 2 столбцами? - PullRequest
5 голосов
/ 09 февраля 2010

Если у меня есть следующая таблица:

ID | Имя | Категория | Родитель | URL | LastModified

Если две строки имеют одинаковое имя и родительский элемент, то они не являются уникальными. Как получить уникальный набор строк в этом случае (но вернуть больше столбцов, которые делают их уникальными)?

Итак, для более подробной информации: Это корпоративная таблица ключевых слов, в которой ключевые слова упорядочены по категориям. Каждое ключевое слово может иметь только одну категорию. Каждое ключевое слово может иметь дочерние ключевые слова, поэтому, если parent = 0 или NULL, это ключевое слово root. Если ключевые слова имеют одно и то же имя и родительский элемент в категории, то они не являются уникальными (независимо от других столбцов). Если два ключевых слова имеют одинаковые имя и категорию, а parent = 0 или NULL, то они не являются уникальными. Если есть дубликаты, то я хочу только 1-й. Причина в том, что я помещаю их в систему, которая не позволяет ключевому слову иметь двух детей с одинаковым именем.

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

Спасибо миллион за отличные ответы. Я, очевидно, не парень SQL ...: (

Ответы [ 4 ]

7 голосов
/ 09 февраля 2010

Это зависит от того, что вы хотите сделать с неуникальными строками. Если вы хотите, чтобы их не было в наборе результатов, вы можете использовать group by и иметь:

select Name, Parent, Max(Category) 
from Table
group by Name, Parent
having count(*) = 1

Вам нужен Max (Категория), потому что вы не группируете по этому столбцу, даже если для Имени и Родителя будет только одна строка.

Если, однако, вы хотите включить в результат неуникальные строки, аналогично:

select distinct Name, Parent, Category from Table

за исключением того, что две строки с одинаковыми именами и родителями, но с другой категорией, возвращают только одну строку. В этом случае вам нужно решить, что показывать для категории, так как более одной строки будет сжато до одной. Вы по-прежнему можете использовать Макс (Категория) или Мин (Категория) и группировать по, но оставьте без.

select Name, Parent, Max(Category) 
from Table
group by Name, Parent
4 голосов
/ 09 февраля 2010

Этот запрос находит все строки, где ни одна другая строка не имеет такого же имени и родительского элемента. Если для двух строк родительский элемент имеет значение NULL, считается, что эти строки не имеют одинакового родителя.

SELECT T1.*
FROM Table1 T1
LEFT JOIN Table1 T2
ON T1.ID != T2.ID AND T1.Name = T2.Name AND T1.Parent = T2.Parent
WHERE T2.ID IS NULL
2 голосов
/ 09 февраля 2010

Вы можете использовать функцию row_number для разделения по Имени и Родителю, например:

select *
from (
    select
        row_number() over (partition by Name, Parent 
                           order by Name, Parent) as rn
    ,   *
    from YourTable
) sub
where rn = 1 -- Only first row for a name/parent combination

Если вы хотите выбрать только строки, которые являются уникальными, в том смысле, что других строк с таким же именем и родителем не существует, попробуйте:

select *
from YourTable a
where (
    select count(*)
    from YourTable b
    where a.Name = b.Name
    and a.Parent = b.Parent
) = 1
1 голос
/ 09 февраля 2010
select x,y,z
from tablename t1
where not exists (select 1 from tablename t2 where t2.name = t1.name and t1.parent = t2.parent and t2.id <> t1.id)

может работать медленно в зависимости от размера таблицы

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