使用SQL DB for i的行的最高百分比

时间:2013-01-22 14:19:44

标签: sql odbc db2 ibm-midrange

我正在尝试获得一个返回值,它给出了返回值的前80%。使用SQL DB for i TOP子句将不起作用。我已经看到了一些在嵌套的select语句中使用Count()的例子,但我不确定它应该如何适合我已经编写的查询。我已经有2个子查询,所以我需要找出它是如何适合的,或者它是否适用。以下是我到目前为止的情况:

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的东西,所以如果问题看起来有点简单,我很抱歉。

3 个答案:

答案 0 :(得分: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子句来获取所需的值。

答案 1 :(得分:1)

首先,你的子选择是不必要的, 我发现使用更简单的连接语句更容易阅读。 如果您折叠子查询,则使用count(*)的技术 更容易融入。

接下来,向现有查询添加计数存在问题。 如果您已经在使用count,那么添加连接并计数 因为联接创建了一个笛卡尔积,所以可能会破坏这两个数 并且计数和总和可能得到错误的答案。 你还没有数数或总和,所以你不必担心 陷阱。

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   

答案 2 :(得分: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