2009-12-17 63 views
32

正如標題所示,我使用的是SQL Server 2008.如果此問題非常基本,請道歉。我只用了幾天的SQL。現在,我有以下查詢:SQL Server 2008:排名前10並且分離在一起

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 

我想要做的是使用SELECT TOP N一起與ID列不同的值。通過一些論壇搜索說,使用

SELECT DISTINCT TOP 10 ... 

但是當我

SELECT DISTINCT TOP 10 p.id, pl.nm, pl.val, pl.txt_val 

取代第一線,我得到了相同的結果無字不同。我應該怎麼做才能過濾出重複的ID條目?

謝謝。

+1

我認爲你需要更明確地陳述你的問題。如果你有三行p.id = 1,那麼你想要哪一行?最高或最低的pl.nm,pl.val,pl.txt_val,某種組合或其他的東西? SQL不能以這種方式應用DISTINCT(),但有辦法每個p.id獲得一行。你只需要定義需求,我們可以幫助... – 2009-12-18 03:07:24

+0

Patients.ID是主鍵嗎? – dan 2009-12-18 06:25:51

回答

9

最簡單的選擇是,選擇最小/最大所有其他字段

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 

這可以得到寬表相當繁瑣,因此另一種選擇是使用秩過來partiion

使用組
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 
+3

我不認爲這是被允許的。您無法引用WHERE子句中SELECT列表中創建的列。 – siride 2013-04-23 21:13:50

+1

看看Halim剛纔的答案如下:https://stackoverflow.com/a/37642799/4212710 – typoerrpr 2017-08-03 04:05:25

+0

'簡單的選項' – eddyP23 2018-01-16 16:05:00

1
select top 10 * from 
(
    select distinct p.id, .... 
) 

將工作。

+0

盡我所見,他希望不同的ID值,所以這不會起作用 – 2009-12-17 23:10:04

0

DISTINCT刪除行如果全部選定的值是相等的。很明顯,你有與p.id相同的條目,但是有不同的pl.nm(或pl.valpl.txt_val)。您的問題的答案取決於您想要在一個行中顯示哪一個值,並且您的p.id(第一個?最小?任意?)。

4

一些想法:

  1. 您的SELECT語句中相當多的領域。任何不同於另一個的值都會使該行不同。
  2. TOP子句通常與WHERE子句配對。否則TOP並不意味着太多。什麼東西?指定「top of what」的方式是使用WHERE
  3. 即使使用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邏輯。

0

我認爲問題是,你想每個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 

不會需要不同的關鍵字即可。

+0

-1以這種方式使用MAX將使結果集任意。 – 2009-12-17 23:25:44

+0

是的,但是如果你想每個p.id得到一個結果,你將不得不做任意的事情或完全離開這些列 – MikeW 2009-12-18 01:00:14

+1

不一定,如果你想要爲每個p.id的特定行關聯的行,例如具有max(nm)或max()的那個,則需要整行,而不是可能不同行中的隨機最大值。 Paul Creasey給出的解決方案只需通過over()子句內的順序來改變順序就可以做到這一點。不知道什麼懦夫在沒有說明他/她的理由的情況下低估了他的答案。 – 2009-12-18 03:05:29

0

你可以使用一個公用表表達式,以獲得最高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:爲什麼你甚至不加入「病人」表,如果你從不選擇任何領域?

2

我知道這個線程是舊的,但我想我會拋出什麼,因爲我剛剛遇到了同樣的問題。這可能效率不高,但我相信它可以完成工作。

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) 
0
SELECT TOP 14 A, B, C 
    FROM MyDatabase 
    Where EXISTS 
    (
    Select Distinct[A] FROM MyDatabase 
    ) 
24
select top 10 p.id from(select distinct p.id from tablename)tablename 
+0

簡單而優雅。應該是最高票數的答案。 – 2015-06-28 16:27:24

+0

我不認爲這是有效的,因爲不同的命令id是遞增的 – 2016-08-04 14:37:01

0

這是正確的答案,你可以找到從表

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 
67

3高值嘗試

SELECT distinct TOP 10 MyId FROM sometable 
+7

這是正確的答案 – Hans 2016-12-02 12:56:16

+0

這也適用於Sybase 12以及 – 2017-04-28 20:55:53

+0

只需切換它們即可。非常好。 – 2017-05-21 23:22:19

1

好,我也沒有想到它,但哈利姆的 選擇不同的TOP 10 MyId從一些表

在功能上等同Vaishnavi Kumar的 從(選擇表名不同p.id)表名

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 

產生用於既選擇了相同的結果選擇頂部10 p.id:

name 
1 bob 
2 jim 
3 john 
4 luke 
5 mark 

奇怪的是,選擇前5個獨立無效,但選擇不同的前5個是,並且可以像你期望的那樣選擇前5個獨立的工作。