2009-07-26 64 views
1

給定一個表Records與列id intType intName varchar(50)限制結果記錄,我可以讓搜索查詢,像這樣:平衡不同類型的由TOP 100

SELECT id, Type, Name 
FROM Records 
WHERE Name LIKE '%Foo%' 

要調整的表現的話,我'只想給出有限的結果;目前爲100 - 只需在聲明中添加TOP 100即可。然而,這可能會導致某些類型的記錄代表性不足或沒有代表所有的,因爲通過如下所示的查詢:

SELECT Type, COUNT(Type) FROM 
    (SELECT id, Type, Name 
    FROM Records 
    WHERE Name LIKE '%Foo%') x 
GROUP BY Type 
ORDER BY Type 

沒有TOP 100,我可能會得到:

42 5 
49 1 
50 1 
52 1 
59 1 
76 40 
87 567 
90 3 

...與它:

42 5 
49 1 
50 1 
52 1 
59 1 
76 26 
87 65 

這可能會導致用戶的結論是沒有90類型的記錄存在。

我寧願TOP表現不同:給我任何類型,其中有一些至少一個結果,然後繼續增加,直到達到計數。例如,42,7687將具有較少的結果,但會出現90

理想情況下,我還想爲用戶提供「此類型的更多結果」UI元素。

我必須完全放棄TOP才能做到這一點嗎?

+0

如果刪除到100,還有就是你所看到的結果。你想如何結果? – shahkalpesh 2009-07-26 20:10:12

+1

tsql是Transact SQL的常用標記,而不是t-sql。我已修復。 – 2009-07-27 04:50:17

回答

3
WITH RecordsWithRn AS (
SELECT id, Type, Name, 
    ROW_NUMBER() OVER (PARTITION BY Type ORDER BY ... intra-type ordering ...) as rn 
     FROM Records 
     WHERE Name LIKE '%Foo%') 
SELECT TOP 100 id, Type, Name 
    FROM RecordsWithRn 
    ORDER BY RN, ... inter-type ordering ... 

這給你一個百條記錄。每種類型至少有一種,假設少於100種。使用ROW_NUMBER()的ORDER BY來控制類型中記錄的ROW_NUMBER的順序。最後一個ORDER BY,按先前分配的row_number進行排序,然後添加其他條件(如果需要),以控制每個row_number的類型之間的記錄順序。

編輯:要獲取的未所示類型的記錄數:

WITH RecordsWithRn AS (
    SELECT id, Type, Name, 
     ROW_NUMBER() OVER (PARTITION BY Type ORDER BY Type) as rn, 
     COUNT(*) OVER (PARTITION BY Type) as CountType 
    FROM Records 
    WHERE Name LIKE '%Foo%') 
, Top100Records as (
    SELECT TOP 100 id, Type, Name, CountType 
    FROM RecordsWithRn 
    ORDER BY RN) 
select Id, Type, Name, 
    CountType - (COUNT(*) over (PARTITION BY Type)) as CountTypeNotIncluded 
from Top100Records 
0

你可以做兩個電話。第一個是[type]和count([type])。這將提供所有可用類型的唯一列表以及它們的計數以獲取更多信息給用戶。之後,按用戶請求的方式調用每種類型的電話。

1
WITH cte AS (
SELECT id, Type, Name, 
    ROW_NUMBER() OVER (PARTITION BY Type ORDER BY Type) as rn 
     FROM Records 
     WHERE Name LIKE '%Foo%') 
SELECT * 
    FROM cte 
    WHERE rn <= 100; 

這將從每個類型獲得至多100條記錄。請注意,這絕不意味着查詢速度會更快,實際上它可能會更慢。它取決於可用的索引,表中的數據以及客戶端能夠處理結果的速度。

如果可以顯示每種類型的總數,則必須計算它:

WITH totals AS (
    SELECT Type, COUNT(*) AS count 
      FROM Records 
      WHERE Name LIKE '%Foo%' 
    GROUP BY Type) 
SELECT * FROM totals; 

再加入兩個結果:

​​
+0

你的代碼實際上返回了太多的行(在我的情況下爲152),並且似乎比Shannon的解決方案慢(700 ms的執行時間與348.67 ms,平均在三次運行中),但無論如何我都贊成你,因爲它非常接近。 :) – 2009-07-27 06:53:30