2013-01-22 40 views
2

我想獲得返回值,它給出返回值的前80%。使用SQL DB for TOP子句將不起作用。我已經看到了在嵌套select語句中使用Count()的一些示例,但我不確定這是如何適合我已經編寫的查詢的。我已經有2個子查詢,所以我需要找出它是如何適合的,或者它是否會起作用。以下是我迄今爲止:我使用SQL DB的行數最高的百分比

Select CATEGORY, 
    LINE, 
    ITEM#, 
    Units 
From D*****.*****ST 
Inner Join (Select DW******.*****FO.ITEM, 
        Sum (SALES_UNITS) As Units, 
        CATEGORY 
      From DW*******.*****FO 
      Inner Join (Select CATEGORY, 
           DW****.******RY.ITEM 
         From DW****.******RY 
         Where CATEGORY='BRAKES') As CA***ST 
      On DW*******.*****FO.ITEM=CA*****.***M    
      Where ("DATE" between current date -1 years and current date) And (SALES > 5.00) 
      Group By DW*******.******O.ITEM, 
         CATEGORY) As Units_List 
On  DW****.*****ST.**EM#=U*********.***M 
Group By CATEGORY, 
      LINE, 
      ITEM#, 
      Units 
Order By Units DESC    

所以在這裏的某個地方將是嵌套Count()條款我假設,我只是不知道在那裏它適合在事物的宏偉計劃。我仍然在學習一些中間SQL的東西,所以如果問題看起來有點簡單,我很抱歉。

+1

這些星號是否真的在表和列名中?如果沒有,請不要在將來這樣做;他們讓你的代碼示例難以閱讀。另外,你使用的是什麼數據庫?你標記了這個「ibm-midrange」;這是DB2嗎? – BellevueBob

+0

不,星號不在實際查詢中。但是,出於安全原因,我標出了一般的DB結構和表名。我想我可以寫出名字而不是星號。是的,它是DB2。 – William

回答

2

我會建議使用窗口函數。我發現您的查詢難走,但這裏的理念是:

select t.* 
from (select t.*, 
      row_number() over (order by units desc) as seqnum, 
      count(*) over() as totnum 
     from (<view that gets you all the data you want> 
      ) t 
    ) t 
where seqnum <= 0.8*totnum 

的想法是使用窗口函數來獲得總計數也排名(我用row_number()rank()可能是,如果你有更合適領帶)。然後,您可以使用where子句獲取所需的值。

+0

一般結構是使用內部連接作爲連接的Query(子查詢(子查詢))。這會進入最初的查詢,還是其中一個子查詢? – William

+0

感謝Gordon的幫助,這幫助我解決了一般問題! – William

0

這是一般的Oracle示例,可能對您有所幫助。我不知道你正在使用的數據庫:

SELECT deptno, ename, sal 
    , PERCENT_RANK() OVER (PARTITION BY deptno ORDER BY sal DESC) AS prcnt 
    FROM scott.emp 
ORDER BY prcnt DESC, sal, ename 
/

DEPTNO  ENAME SAL  PRCNT 
-------------------------------- 
10   MILLER 1300 1 
... 
20   ADAMS 1100 0.75 
30   MARTIN 1250 0.6 
... 
10   CLARK 2450 0.5 
... 
30   TURNER 1500 0.4 
+0

這不起作用。他在DB2上爲我。 – WarrenT

1

嗯,首先,你的子選擇是不必要的, ,我發現很容易用一個簡單的連接語句讀取。 如果你摺疊你的子查詢,計數(*)技術將更容易合併 。

接下來,將計數添加到現有查詢存在問題。 如果您已經使用count,那麼添加連接並計數 可能會混淆兩個計數,因爲連接會創建笛卡爾積, 並且count和sum可能會得到錯誤的答案。 你還沒有數量或總和,所以你不必擔心這個缺陷。

Select RY.CATEGORY, ST.LINE, ST.ITEM#, FO.Units 
From D*****.*****ST ST 
    Inner Join DW*******.*****FO FO On ST.ITEM# = FO.ITEM 
    Inner Join DW****.******RY RY On FO.ITEM = RY.ITEM 
    And ("DATE" between current date -1 years and current date) 
    And (SALES > 5.00) 
    Inner Join D*****.*****ST ST_J On ST.LINE = ST_J.LINE And ST.ITEM# = ST_J.ITEM# 
    Inner Join DW*******.*****FO FO On ST_J.ITEM# = FO_J.ITEM 
Where FO_J.Units >= FO.Units 
Group By RY.CATEGORY, ST.LINE, ST.ITEM#, FO.Units 
Having  Count(FO_J.Units) < 0.8 * (Select Count(*) 
     From D*****.*****ST ST_J On ST.LINE = ST_J.LINE And ST.ITEM# = ST_J.ITEM# 
     Inner Join DW*******.*****FO FO On ST_J.ITEM# = FO_J.ITEM) 
Order By FO.Units DESC 
+0

我喜歡這個答案,我再一次對整個SQL有所瞭解。我很好奇,但爲什麼嵌套的子查詢效率低於5個不同的連接?我們使用的一些表格非常龐大,所以如果以這種方式構建查詢更高效,那麼我完全贊成。 – William

+0

這只是一個可讀性的東西。我假設SQL引擎中的優化器將作出更有效運行作業的正確選擇。關鍵是,按照我寫這些JOIN的方式,通過添加一個計數可以更容易地進行更改。 –