2014-02-05 55 views
1

可以說我有很多的SQL語句像這樣的:獲得的行數的SELECT語句將獲取(無實際取)

select * 
    from [A] 
    where a in (
     select a 
      from [B] 
      where b = 'c' 
     ) 
order by d; 

由於我的數據庫是巨大的,我只需要確定有多少行此查詢將取。當然,我可以真正獲取所有行並計算它,但我的目的是避免提取,因爲這會造成很大的開銷。

我曾試圖擴大查詢,如下所示:

select count (*) 
    from (
      select * 
      from [A] 
      where a in (
        select a 
        from [B] 
        where b = 'c' 
       ) 
     order by d 
     ) as table; 

,對於一些表,但對於一些正常工作(像這樣的例子)SQL Server會拋出這樣的:

ORDER BY子句在視圖,內聯函數,派生表,子查詢和公用表表達式中是無效的,除非還指定了TOP或FOR XML。

考慮到我不能改變任何原始查詢,我可以擴展它...

任何想法? 謝謝。

編輯:我敢肯定有對@@ ROWCOUNT領域相關的一些解決方案,但不知道如何使用它...

+1

真正的問題是要求。在抓取時抓取並計數。取數之前計數是資源的浪費,服務器必須做兩次這項工作。沒原因。 –

+0

僅僅通過添加周圍的語法,就不可能像'SELECT * FROM T ORDER BY C'那樣將查詢轉換爲計數查詢。你可以做的一件事是查看它的估計執行計劃並查看估計的行數。雖然可能不準確。 –

回答

2

只需卸下order by子查詢。它不影響的行數:

select count(*) 
from (select * 
     from [A] 
     where a in (select a from [B] where b = 'c') 
    ) as table; 

其實,這是更好的寫法如下:

select count(*) 
from [A] 
where a in (select a from [B] where b = 'c') 

也就是說,僅僅是select *select count(*)取代。

最後,如果你要不斷的查詢相同,則使用top 100 percent

select count(*) 
from (select top 100 percent * 
     from [A] 
     where a in (select a from [B] where b = 'c') 
     order by d 
    ) as table; 

確實需要改變原有的查詢,但在某種程度上這並不影響他們輸出什麼,做允許它們用作ctes /子查詢。

如果您還使用top,則允許您在子查詢中使用order by

編輯:

如果使用動態SQL,你可能需要做一些事情,如:

@sql = 'select count(*) from (' + 
     (case when @sql not like 'SELECT TOP %' 
      then stuff(@sql, 1, 7, 'SELECT top 100 percent') 
      else @sql 
     end) + 
     + ')'; 

的邏輯可能是更復雜一點,如果你的SQL的格式不正確。

+0

「我不允許更改任何原始查詢,我只能擴展它」 –

+0

@MartinSmith。 。 。答案現在解決了這個問題。我對於「擴展」查詢的含義有點模糊。 –

+0

謝謝大家,但馬丁是對的。原始查詢必須保持不變。 – Filip