2012-07-20 66 views
0

當我做出這個選擇時,它顯示所有「車轍」與它的電話號碼,我的問題 是每個「車轍」有近10個電話號碼,我只需要3個電話號碼每個「車轍」,我嘗試使用TOP,但只顯示所有表的前3行,而不是由「車轍」第一行 ,我怎麼可以使用TOP只是爲行「車轍」,而不是在所有的 表每組返回前3行

Select Distinct 
t1.rut_cliente as rut_cliente, 
t1.nro_fono as numero 
--Into #tmp_numeros 
From dat_clientes_sucursales_contactos_telefonos t1,dat_rut_clientes t2 
where t1.rut_cliente = t2.rut_cliente 
and cod_prioridad = 1 

這就是我得到這個查詢:

Rut_cliente Nro_fono 
    60506000-5 2046840 
    60506000-5 3507935 
    60506000-5 4106886 
    60506000-5 5440000 
    60506000-5 5445000 
    81698900-0 2373281 
    81698900-0 3541342 
    81698900-0 3541438 
    81698900-0 3541518 
    81698900-0 3542101 

,這就是我想要的:

Rut_cliente Nro_fono 
    60506000-5 2046840 
    60506000-5 3507935 
    60506000-5 4106886 
    81698900-0 2373281 
    81698900-0 3541342 
    81698900-0 3541438 

在此先感謝。

回答

7

問題最初被標記的SQL Server 2008,在那裏你可以使用一個公用表表達式做到這一點:

;WITH x AS 
(
    SELECT Rut_cliente, Nro_fono, rn = ROW_NUMBER() 
    OVER (PARTITION BY Rut_cliente ORDER BY Nro_fono) 
    FROM dbo.dat_clientes_sucursales_contactos_telefonos AS t1 
    INNER JOIN dbo.dat_rut_clientes AS t2 
    ON t1.rut_cliente = t2.rut_cliente 
    WHERE cod_prioridad = 1 
) 
SELECT Rut_cliente, Nro_fono FROM x 
WHERE rn <= 3 
ORDER BY Rut_cliente, Nro_fono; 

其他評論:

  • 請不要使用table, table語法。使用正確的INNER JOIN s。我explain why here
  • 請在內部查詢中添加適當的別名,以便人們知道哪些列來自t1,哪些列來自t2。

但現在我們瞭解用戶實際使用的SQL Server 2000。這是我會怎麼做它在那裏,我想,但性能將是可怕的。我不是100%確定這是有效的(因爲我再次猜測哪些列來自哪個表)。

SELECT x.rut_cliente, x.nro_fono, COUNT(*) FROM 
(
    SELECT t1.rut_cliente, t1.nro_fono 
    FROM dat_clientes_sucursales_contactos_telefonos AS t1 
    INNER JOIN dat_rut_clientes AS t2 
    ON t1.rut_cliente = t2.rut_cliente 
    WHERE cod_prioridad = 1 
) AS x 
INNER JOIN dat_clientes_sucursales_contactos_telefonos AS b 
ON b.rut_cliente = x.rut_cliente 
AND b.nro_fono <= x.nro_fono 
GROUP BY x.rut_cliente, x.nro_fono 
HAVING COUNT(*) <= 3 
ORDER BY x.rut_cliente, x.Nro_fono; 
+0

對於有用的提示+1並在12秒內擊敗我。 – 2012-07-20 19:53:09

+1

@蒂姆謝謝,讓我們小心一點,不要像投票戒指。 :-) – 2012-07-20 20:03:17

5

例如與ROW_NUMBER這是一個窗函數,並返回一個行號由order by確定的每個分區(類似於group by):

WITH CTE AS(
    SELECT t1.rut_cliente as rut_cliente, t1.nro_fono as numero, 
     RN = ROW_NUMBER()OVER(PARTITION BY Rut_cliente ORDER BY Nro_fono) 
    FROM dbo.dat_clientes_sucursales_contactos_telefonos AS t1 
    INNER JOIN dbo.dat_rut_clientes AS t2 ON t1.rut_cliente = t2.rut_cliente 
    WHERE cod_prioridad = 1 
) 
SELECT rut_cliente as rut_cliente, nro_fono as numero 
FROM CTE 
WHERE RN <= 3 
+0

+1,因爲你重寫了這個連接,因爲我只打了你12秒。 :-) – 2012-07-20 19:50:56

+0

@Tim Schmelter 當我使用你的代碼我得到這個:'ROW_NUMBER'不是函數的名字 – suely 2012-07-20 19:51:45

+1

@suely你的文章說你正在使用SQL Server 2008.你確定嗎?也許這就是您正在使用的Management Studio版本,但是您正在連接到SQL Server 2000?什麼是「SELECT @@ VERSION;'產量? – 2012-07-20 19:59:32

0

嘗試此

;with CTE AS (
select Rut_cliente, Nro_fono , ROW_NUMBER() OVER 
(PARTITION BY Rut_cliente ORDER BY Nro_fono) rn 
FROM dbo.dat_clientes_sucursales_contactos_telefonos AS a 
INNER JOIN dbo.dat_rut_clientes AS b 
ON a.rut_cliente = b.rut_cliente 
WHERE cod_prioridad = 1 

) 
SELECT * FROM CTE where rn <=3 
+0

感謝您指出,現在修復。這是一個供用戶使用的示例查詢,用戶可以替換@table與表名和連接 – 2012-07-20 20:04:23