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

Oli*_*ver 28 sql

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

我想创建一个搜索,只为每个用户返回一个条目,即使该用户有多个地址.无论搜索找到什么地址都足够了,搜索回退的地址无关紧要.

以下是搜索结果示例:

tst  olix  Chicago  IL  USA
tst  olix  Los Angeles  CA  USA
tst2 olix2 Houston  TX USA
Run Code Online (Sandbox Code Playgroud)

我需要搜索它只返回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
Run Code Online (Sandbox Code Playgroud)

ype*_*eᵀᴹ 10

如果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
Run Code Online (Sandbox Code Playgroud)

使用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
Run Code Online (Sandbox Code Playgroud)

  • SQL-Server有`TOP` (2认同)

Mat*_*hew 7

您可能需要使用GROUP BY而不是DISTINCT在这种情况下.

现在发布您的查询,我会帮助您更多.

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

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

SELECT 
    userID
    , FIRST(address)
FROM
    yourTable
GROUP BY
    userID
Run Code Online (Sandbox Code Playgroud)


JNK*_*JNK 6

SELECT Name, MAX(Address), MAX(other field)...
FROM MyTable
GROUP BY Name
Run Code Online (Sandbox Code Playgroud)

会给你一排Name.

  • @Matthew - 他在问题中说他不关心他得到哪一个.我认为他可能会关心这些字段是否相互关联(即`Address1,City,State,Zip`) - 你可能会得到错误的状态/地址组合,这会很糟糕 (4认同)

dan*_*ana 6

假设地址表有一个 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)
Run Code Online (Sandbox Code Playgroud)

我的查询返回所有有地址的人。该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)
Run Code Online (Sandbox Code Playgroud)

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