2

我试图获得一个返回值的前 80% 的返回值。使用 SQL DB for iTOP子句将不起作用。我已经看到了一些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 的东西,所以如果问题看起来有点简单,我很抱歉。

4

3 回答 3

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子句来获取您想要的值。

于 2013-01-22T14:24:02.573 回答
1

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

接下来,向现有查询添加计数存在问题。如果您已经在使用 count,那么添加连接和计数可能会混淆两个计数,因为连接会创建笛卡尔积,并且 count 和 sum 可能会得到错误的答案。你还没有 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   
于 2013-01-22T14:50:29.483 回答
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
于 2013-01-22T14:45:27.707 回答