SQL - 'DISTINCT'仅基于某些列?

时间:2011-07-22 15:27:14

标签: sql

我有一个包含两个表的数据库。其中一个表包含用户,另一个表包含这些用户的地址。每个用户可能有多个地址(尽管每个地址只与一个用户绑定。)

我想创建一个只为每个用户返回一个条目的搜索,即使该用户有多个地址。无论搜索首先找到什么地址都没关系,这无关紧要。

以下是搜索结果示例:

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

5 个答案:

答案 0 :(得分:9)

如果AddressesID字段:

(针对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

答案 1 :(得分:8)

在这种情况下,您可能需要使用GROUP BY代替DISTINCT

立即发布您的查询,我会为您提供更多帮助。

或者,如果您只想返回第一个地址,则完全是另一个查询。是否需要返回地址?你需要什么数据?在这种情况下,“第一”意味着什么?如何订购数据?

任意你可以做这样的事情(未经测试),具体取决于你的数据库:

SELECT 
    userID
    , FIRST(address)
FROM
    yourTable
GROUP BY
    userID

答案 2 :(得分:5)

SELECT Name, MAX(Address), MAX(other field)...
FROM MyTable
GROUP BY Name

Name会给你一行。

答案 3 :(得分: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()子句用于确定返回的地址具有分配给该人的最低地址ID。结果每人只包含1个地址。


编辑:另一种使用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)

这应该非常有效,因为嵌套查询会在为每个人找到的第一个地址上短路。

答案 4 :(得分:0)

尝试聚合:

SELECT user, address FROM users
JOIN addresses ON (users.user_id = addresses.user_id)
GROUP BY user;