Как запустить DISTINCT для неключевых в SQL - PullRequest
0 голосов
/ 11 сентября 2011

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

столбцы: _id, name, img, address, available

Две записи могут выглядеть следующим образом:

_id | name | img                | address   | available
-------------------------------------------------------
1   | John | http://img.com/222 | 1 Main St | 1
2   | John | http://img.com/222 | 1 Main St | 0

Я хочузапрос, который выдаст мне все результаты с отдельным ключом, и, если есть повторяющиеся записи (игнорируя тот факт, что _id будет другим), он вернет только первый.Вот мой запрос:

SELECT p1.* 
FROM (SELECT DISTINCT _id, available FROM people) p
    INNER JOIN people p1
    ON p1._id=p._id
ORDER BY p1.available DESC;

Я знаю, что это неправильно, но, возможно, это немного объясняет то, что я ищу.Хотел бы я использовать GROUP BY здесь?

Ответы [ 4 ]

1 голос
/ 11 сентября 2011

I want a query that will give me all results that have a distinct key, and if there are duplicate entries(ignoring the fact that _id would be different), it will give back only the first one.....the _id isn't what I want to be distinct, as they [the ids] are already unique. ... . Ideally it will order by 'available' in descending order so that if there are two columns with the same data(aside from _id and available), it will return the row with '1' for the available column

             select name, image, address, max(availability) as avail
              from T
             group by name, image, address

Затем вы можете присоединить набор, возвращенный запросом выше, в виде встроенного представления, к вашей таблице:

            select * from T
            inner join
            (

             select name, image, address, max(availability) avail
              from T
             group by name, image, address
            ) as foo

            on T.name = foo.name and T.image = foo.image and T.address = foo.address and T.availability = foo.avail

Это поможет получитьсоставной индекс так: (имя, изображение, адрес).

Предостережение: если имеется более одной строки, в которой конкретная триада {имя, изображение, адрес} имеет доступность = 1, запрос возвратит несколько строкдля триады:

             2   | John | http://img.com/222 | 1 Main St | 1
             6   | John | http://img.com/222 | 1 Main St | 1

PS Звучит так, как будто вы хотели, чтобы триада (имя, изображение, адрес) была создана в вашей таблице альтернативным уникальным ключом.

0 голосов
/ 12 сентября 2011

Если вам нужна первая строка с наименьшим значением _id среди тех, которые имеют наибольшее значение available (от 1 до 0), вы можете «записать» _id внутри агрегированного значения, сгенерированного группировкой.

Значение для сравнения строится таким образом, что упорядочивает запись по их полю available в порядке убывания, а затем по полю _id в порядке убывания и позволяет легко извлечь значение_id с оператором по модулю (при условии, что доступное максимальное значение равно 1, а идентификаторы никогда не превышают 100000000).

select people.* from people 
inner join ( 
    select name, img, address, 
    min((1-available)*100000000 + _id) avail_id 
    from people group by name, img, address
) as foo on people._id = foo.avail_id % 100000000;

Я адаптировал его Запрос Тима .

Вы также можете сделать это без подзапроса :

select people.* from people 
left outer join people as other on 
    other.name = people.name and 
    other.img = people.img and 
    people.address=other.address and 
    (1 - people.available) * 100000000 + people._id > 
        (1 - other.available) * 100000000 + other._id 
where other.available is null;
0 голосов
/ 11 сентября 2011

Я на самом деле только что задал похожий вопрос и получил отличный ответ от опытного пользователя здесь:

SQL Заполнение различными данными и последовательностью

Исходя из того, что он сказал мне, возможно, этот запрос даст вам то, что вы хотите:

SELECT p1.* 
FROM (SELECT DISTINCT _id, name from people) p
   INNER JOIN people p1
   ON p1._id=p._id
ORDER BY p1.available desc

извинения, если это не удалось и не работает!

РЕДАКТИРОВАТЬ: Мне пришло в голову, что я понятия не имею, какое отдельное имя + _id комбо это извлечет .. доступны = 1 или доступны = 0 или случайный выбор ..! Дайте мне знать, что происходит в любом случае ..

0 голосов
/ 11 сентября 2011

этот sql может решить вашу проблему:

выберите b. * Из (выберите отличный _id от людей) a, люди b, где a._id = b._id порядок на b.available

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