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 10DISTINCT 【参考方案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/4212710 The 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.valpl.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 2008和mysql的区别

SQL Server Update:使用 TOP 限制更新的数据

怎么使用sql server查询显示第10条到第20条信息?

当表名包含“'”时为 Sql Server 2008 构建动态查询

SQL Server 2008r2 提交性能问题

跪求好心人分享win10版sql server 2008 中文版软件免费百度云资源