Jus*_*808 21 sql sql-server sql-server-2000 greatest-n-per-group
我有一点SQL几乎正在做我想要它做的事情.我正在使用三个表,一个是Users,UserPhoneNumbers和UserPhoneNumberTypes.我正在尝试获取一个用户列表,其中包含用于导出的电话号码.
数据库本身很旧并且存在一些完整性问题.我的问题是,数据库中每个电话号码应该只有1种类型,但事实并非如此.当我运行这个时,我得到每个人的多行结果,如果它们包含例如两个"Home"数字.
如何修改SQL以获取列出的第一个电话号码并忽略其余的号码?我在SQL Server中,我知道TOP语句.但是,如果我将"TOP 1"添加到LEFT JOIN select语句,它只是给我数据库中的第一个条目,而不是每个用户的第一个条目.
这适用于SQL Server 2000.
谢谢,
SELECT Users.UserID,
Users.FirstName, Users.LastName,
HomePhone, WorkPhone, FaxNumber
FROM Users
LEFT JOIN
(SELECT UserID, PhoneNumber AS HomePhone
FROM UserPhoneNumbers LEFT JOIN UserPhoneNumberTypes ON UserPhoneNumbers.UserPhoneNumberTypeID=UserPhoneNumberTypes.UserPhoneNumberTypeID
WHERE UserPhoneNumberTypes.PhoneNumberType='Home') AS tmpHomePhone
ON tmpHomePhone.UserID = Users.UserID
LEFT JOIN
(SELECT UserID, PhoneNumber AS WorkPhone
FROM UserPhoneNumbers LEFT JOIN UserPhoneNumberTypes ON UserPhoneNumbers.UserPhoneNumberTypeID=UserPhoneNumberTypes.UserPhoneNumberTypeID
WHERE UserPhoneNumberTypes.PhoneNumberType='Work') AS tmpWorkPhone
ON tmpWorkPhone.UserID = Users.UserID
LEFT JOIN
(SELECT UserID, PhoneNumber AS FaxNumber
FROM UserPhoneNumbers LEFT JOIN UserPhoneNumberTypes ON UserPhoneNumbers.UserPhoneNumberTypeID=UserPhoneNumberTypes.UserPhoneNumberTypeID
WHERE UserPhoneNumberTypes.PhoneNumberType='Fax') AS tmpFaxNumber
ON tmpFaxNumber.UserID = Users.UserID
Run Code Online (Sandbox Code Playgroud)
假设SQL Server 2005+,请使用ROW_NUMBER:
LEFT JOIN (SELECT UserID,
PhoneNumber AS HomePhone,
ROW_NUMBER() OVER (PARTITION BY userid ORDER BY what?) AS rank
FROM UserPhoneNumbers upn
LEFT JOIN UserPhoneNumberTypes upnt ON upnt.UserPhoneNumberTypeID = upn.UserPhoneNumberTypeID
AND upnt.PhoneNumberType='Home') AS tmpHomePhone
ON tmpHomePhone.UserID = Users.UserID
AND tmpHomePhone.rank = 1
Run Code Online (Sandbox Code Playgroud)
注意what?
占位符以确定第一个数字.如果你根本不关心,请省略ORDER BY ...
无论何时只想从左表中为右表中的每一行选择一行,您应该考虑使用APPLY运算符而不是join,并在左连接内移动连接条件:
SELECT u.UserID,
u.FirstName, u.LastName,
hn.PhoneNumber AS HomePhone
FROM Users u
OUTER APPLY (
SELECT TOP(1) PhoneNumber
FROM UserPhoneNumbers upn
LEFT JOIN UserPhoneNumberTypes upt
ON upn.UserPhoneNumberTypeID=upt.UserPhoneNumberTypeID
WHERE upt.PhoneNumberType='Home'
AND upn.UserID = u.UserID
ORDER BY ...) as hn
...
Run Code Online (Sandbox Code Playgroud)
由于它是SQL Server 2000和排名函数,你可以使你的子查询聚合:
SELECT UserID, MAX(PhoneNumber) AS HomePhone FROM [...] GROUP BY UserID
Run Code Online (Sandbox Code Playgroud)
如果您不在乎返回用户的主页号码...
归档时间: |
|
查看次数: |
42010 次 |
最近记录: |