SQL - "DISTINCT" на основе только нескольких столбцов?
У меня есть база данных с двумя таблицами. Одна из таблиц содержит пользователей, другая содержит адреса для этих пользователей. Каждый пользователь может иметь несколько адресов (хотя каждый адрес привязан только к одному пользователю.)
Я хочу создать поиск, который возвращает только одну запись для каждого пользователя, даже если у этого пользователя несколько адресов. Не имеет значения, какой адрес отскакивает поиск - независимо от того, что поиск находит первым.
Вот пример результата поиска:
tst olix Chicago IL USA
tst olix Los Angeles CA USA
tst2 olix2 Houston TX USA
Мне нужно, чтобы поиск был таким, что он возвращает только 2 строки, а не 3.
Любые идеи?
SELECT DISTINCT
Users.Firstname, Users.Surname, Users.UserId,
Users.Recommendations, Addresses.City, Addresses.Region,
Addresses.Country
FROM
Users INNER JOIN
Addresses ON FT_TBL.UserId = Addresses.UserId
ORDER BY
Users.Recommendations
Ответы
Ответ 1
Если Addresses
имеет поле ID
:
(обновлено для SQL-Server)
SELECT
Users.Firstname,
Users.Surname,
Users.UserId,
Users.Recommendations,
Addresses.City,
Addresses.Region,
Addresses.Country
FROM
Users INNER JOIN
Addresses ON Users.UserId = Addresses.UserId
WHERE Addresses.ID =
( SELECT TOP 1 A2.ID
FROM Addresses AS A2
WHERE Users.UserId = A2.UserId
)
ORDER BY
Users.Recommendations
Использование функций окна и ранжирования SQL-Server:
SELECT
Users.Firstname,
Users.Surname,
Users.UserId,
Users.Recommendations,
Addresses.City,
Addresses.Region,
Addresses.Country
FROM
Users INNER JOIN
( SELECT *
, ROW_NUMBER() OVER (PARTITION BY UserID) AS rn
FROM Addresses
) AS Addresses ON Users.UserId = Addresses.UserId
AND Addresses.rn = 1
ORDER BY
Users.Recommendations
Ответ 2
Вероятно, вам нужно использовать GROUP BY
вместо DISTINCT
.
Отправьте свой запрос сейчас, и я помогу вам больше.
В качестве альтернативы, если вы просто хотите вернуть первый адрес, это другой запрос. Нужно ли возвращать адрес? Какие данные вам нужны? Что означает "первое" в этом контексте? Как упорядочиваются данные?
Произвольно вы можете сделать что-то вроде этого (untested), в зависимости от вашей БД:
SELECT
userID
, FIRST(address)
FROM
yourTable
GROUP BY
userID
Ответ 3
SELECT Name, MAX(Address), MAX(other field)...
FROM MyTable
GROUP BY Name
Дает вам одну строку за Name
.
Ответ 4
Предполагая, что таблица адресов имеет столбец id:
select p.fname, p.lname, a.state, a.country
from person p
join address a on a.personid = p.personid
where not exists
(select *
from address a2
where a2.personid = a.personid
and a2.addressid < a.addressid)
Мой запрос возвращает всех людей с адресами. Предложение exists()
используется для определения того, что возвращенный адрес имеет самый низкий адрес, назначенный человеку. Результат будет содержать только 1 адрес на человека.
EDIT: Другой способ сделать это с помощью top
, который не был показан другими:
select p.fname, p.lname, a.state, a.country
from person p
join address a on a.addressid =
(select top 1 a2.addressid
from address a2
where a2.personid = p.personid)
Это должно быть очень эффективным, так как вложенный запрос будет замыкаться по первому адресу, найденному для каждого человека.
Ответ 5
Попробуйте совокупность:
SELECT user, address FROM users
JOIN addresses ON (users.user_id = addresses.user_id)
GROUP BY user;