SQL Server 2008:TOP 10 和不同的一起
Posted
技术标签:
【中文标题】SQL Server 2008:TOP 10 和不同的一起【英文标题】:SQL Server 2008: TOP 10 and distinct together 【发布时间】:2009-12-17 22:57:19 【问题描述】:正如标题所说,我使用的是 SQL Server 2008。如果这个问题非常基础,我深表歉意。我只使用 SQL 几天。现在我有以下查询:
SELECT TOP 10 p.id, pl.nm, pl.val, pl.txt_val
from dm.labs pl
join mas_data.patients p
on pl.id = p.id
where pl.nm like '%LDL%'
and val is not null
我想要做的是在 id 列中使用 select top n 和不同的值。搜索一些论坛说要使用
SELECT DISTINCT TOP 10 ...
但是当我用
替换第一行时SELECT DISTINCT TOP 10 p.id, pl.nm, pl.val, pl.txt_val
我得到的结果与没有单词 distinct 的结果相同。我应该怎么做才能过滤掉重复的 id 条目?
谢谢。
【问题讨论】:
我认为您需要更明确地说明您的问题。如果你有三行 p.id = 1,那么你想要哪一行?具有最高或最低 pl.nm、pl.val、pl.txt_val、某种组合或完全不同的那个? SQL 不能以这种方式应用 DISTINCT(),但有一些方法可以让每个 p.id 获得一行。您只需要定义需求,我们可以提供帮助... patients.ID 是主键吗? 在接受的答案下方查看如何一起使用TOP 10
和DISTINCT
【参考方案1】:
试试
SELECT TOP 10 distinct MyId FROM sometable;
【讨论】:
只需要切换它们。非常好。 感谢上帝,我一直在绿色复选标记后滚动。 有时在 SO 上有太多过于复杂的答案,我的天……就用这个人!!! 这不适用于 MS SQL:Msg 156, Level 15, State 1, Line 1 Incorrect syntax near the keyword 'DISTINCT'.
但 SELECT distinct TOP 10
有效【参考方案2】:
select top 10 p.id from(select distinct p.id from tablename)tablename
【讨论】:
简洁优雅。应该是投票最多的答案。 我认为这行不通,因为不同的订单 ids 升序【参考方案3】:简单的选项是使用分组依据并为所有其他字段选择最小值/最大值
SELECT TOP 10
p.id,
max(pl.nm),
max(pl.val),
max(pl.txt_val)
from
dm.labs pl
join
mas_data.patients p
on
pl.id = p.id
where
pl.nm like '%LDL%'
and
val is not null
group by
p.id
这对于宽表可能会变得非常乏味,因此另一种选择是使用排名和分区
SELECT TOP 10
p.id,
pl.nm,
pl.val,
pl.txt_val,
rank() over(partition by p.id order by p.id) as Rank
from
dm.labs pl
join
mas_data.patients p
on
pl.id = p.id
where
pl.nm like '%LDL%'
and
val is not null
and
Rank = 1
【讨论】:
我认为这是不允许的。您不能在 WHERE 子句中引用在 SELECT 列表中创建的列。 查看下面哈利姆的回答:***.com/a/37642799/4212710The easy option
这是一个 hack ,充其量是,如前所述,正确答案在下面***.com/a/37642799/183174【参考方案4】:
几个想法:
-
您的选择语句中有很多字段。任何与另一个不同的值都会使该行与众不同。
TOP 子句通常与 WHERE 子句配对。否则 TOP 意义不大。顶什么?您指定“top of what”的方式是使用 WHERE 进行排序
即使使用 TOP、DISTINCT 和 WHERE,也完全有可能获得相同的结果。检查以确保您查询的数据确实能够以您期望的方式进行过滤和排序。
试试这样的:
SELECT DISTINCT TOP 10 p.id, pl.nm -- , pl.val, pl.txt_val
FROM dm.labs pl
JOIN mas_data.patients p
on pl.id = p.id
where pl.nm like '%LDL%'
and val is not null
ORDER BY pl.nm
请注意,我注释掉了一些 SELECT 以限制您的结果集和 DISTINCT 逻辑。
【讨论】:
【参考方案5】:select top 10 * from
(
select distinct p.id, ....
)
会起作用的。
【讨论】:
据我所知,他想要不同的 ID 值,所以这行不通【参考方案6】:我知道这个线程很旧,但我想我会抛出什么,因为我刚刚遇到了同样的问题。它可能效率不高,但我相信它可以完成工作。
SELECT TOP 10 p.id, pl.nm, pl.val, pl.txt_val
INTO #yourTempTable
from dm.labs pl
join mas_data.patients p on pl.id = p.id
where pl.nm like '%LDL%' and val is not null
select p.id, pl.nm, pl.val, pl.txt_val
from #yourTempTable
where id IN (select distinct id from #yourTempTable)
【讨论】:
【参考方案7】:我没想到,但哈利姆的 SELECT distinct TOP 10 MyId FROM sometable
在功能上与 Vaishnavi Kumar 的相同 select top 10 p.id from(select distinct p.id from tablename)tablename
create table #names ([name] varchar(10))
insert into #names ([name]) values ('jim')
insert into #names ([name]) values ('jim')
insert into #names ([name]) values ('bob')
insert into #names ([name]) values ('mary')
insert into #names ([name]) values ('bob')
insert into #names ([name]) values ('mary')
insert into #names ([name]) values ('john')
insert into #names ([name]) values ('mark')
insert into #names ([name]) values ('matthew')
insert into #names ([name]) values ('luke')
insert into #names ([name]) values ('peter')
select distinct top 5 [name] from #names
select top 5 * from (select distinct [name] from #names) subquery
drop table #names
对两个选择产生相同的结果:
name
1 bob
2 jim
3 john
4 luke
5 mark
奇怪的是 select top 5 distinct 是无效的,但是 select distinct top 5 是并且可以正常工作,因为您可能期望 select top 5 distinct 可以工作。
【讨论】:
【参考方案8】:DISTINCT
如果 所有 选定的值相等,则删除行。显然,您的条目具有相同的p.id
但具有不同的pl.nm
(或pl.val
或pl.txt_val
)。您的问题的答案取决于您希望在 one 行中与p.id
一起显示这些值中的哪一个(第一个?最小的?任何一个?)。
【讨论】:
【参考方案9】:我认为问题在于您希望每个 p.id 都有一个结果?
但是对于某些 p.id,您会得到“重复”的结果,对吗?
DISTINCT 关键字适用于整个结果集,因此适用于 pl.nm、pl.val、pl.txt_val,而不仅仅是 p.id。
你需要类似的东西
SELECT TOP 10 p.id, max( p1.nm ), max (p1.val), ...
FROM ...
GROUP BY p.id
那么就不需要 distinct 关键字了。
【讨论】:
是的,但是如果您希望每个 p.id 有一个结果,您将不得不做一些任意的事情或完全不使用这些列 不一定,如果您想要与每个 p.id 的特定行相关联的行,例如具有 max(nm) 或 max() 的行,则需要整行,不是来自潜在不同行的随机最大值。 Paul Creasey 给出的解决方案有可能通过在 over() 子句中更改 order by 来实现这一点。不确定哪个懦夫在没有说明原因的情况下否决了他/她的答案。 同意,这可能更明智。【参考方案10】:您可以使用公用表表达式来获取前 10 个不同的 ID,然后将它们连接到您的其余数据:
;WITH TopTenIDs AS
(
SELECT DISTINCT TOP 10 id
FROM dm.labs
ORDER BY ......
)
SELECT
tti.id, pl.nm, pl.val, pl.txt_val
FROM
TopTenIDs tti
INNER JOIN
dm.labs pl ON pl.id = tti.id
INNER JOIN
mas_data.patients p ON pl.id = p.id
WHERE
pl.nm like '%LDL%'
AND val IS NOT NULL
应该可以。请注意:如果您有一个“TOP x”子句,您通常还需要一个 ORDER BY 子句 - 如果您想要 TOP 10,您需要告诉系统“TOP”是什么顺序。
PS:如果您从未从中选择任何字段,为什么还要加入“患者”表??
【讨论】:
【参考方案11】:SELECT TOP 14 A, B, C
FROM MyDatabase
Where EXISTS
(
Select Distinct[A] FROM MyDatabase
)
【讨论】:
【参考方案12】:这是正确答案,您可以从表格中找到 3 个高度值
SELECT TOP(1) T.id FROM (SELECT DISTINCT TOP(3) st.id FROM Table1 AS t1 , Table2 AS t2 WHERE t1.id=t2.id ORDER BY (t2.id) DESC ) T ORDER BY(T.id) ASC
【讨论】:
【参考方案13】:SELECT DISTINCT * FROM (
SELECT TOP 10 p.id, pl.nm, pl.val, pl.txt_val
from dm.labs pl
join mas_data.patients p
on pl.id = p.id
where pl.nm like '%LDL%'
and val is not null
)
【讨论】:
这将适用于如果您只想删除 (p.id, pl.nm, pl.val, pl.txt_val) 中的重复数据以上是关于SQL Server 2008:TOP 10 和不同的一起的主要内容,如果未能解决你的问题,请参考以下文章
SQL Server Update:使用 TOP 限制更新的数据
怎么使用sql server查询显示第10条到第20条信息?