按列列出的每个多个组的前N个聚合值

时间:2012-12-06 08:02:55

标签: sql vba ms-access

OP的原始问题标题:使用子查询中一个查询的字段

我在Access中编写查询时并不是很有经验,而且我遇到了一些麻烦。

我有几张桌子。 1个用于产品,1个用于市场,1个用于结合市场和产品的事实。我需要编写一个可以将它们连接在一起的查询以及特定市场领域(MF)的每个实例,我需要返回特定事实字段(FF)的第n个最高值(按市场/产品求和)以及哪个特定产品领域(PF),它链接到的事实价值。希望这是有道理的。

无论如何,这是我的查询:

select market.MF2, product.PF10, sum(fact.FF3) as FF3
from mMarket market, mProduct product, mFact fact
where market.Item_ID = fact.Market_ID
and product.Item_ID = fact.Product_ID
and FF3 = 
(
  select min(FF3) from 
  (
    select TOP 2 FF3 from 
    (
      select market2.MF2, product2.PF10, sum(fact2.FF3) as FF3
      from mMarket market2, mProduct product2, mFact fact2
      where market2.Item_ID = fact2.Market_ID
      and product2.Item_ID = fact2.Product_ID
      and market2.MF2 = market.MF2
      group by market2.MF2, product2.PF10
      order by 3 DESC
    )
  )
)
group by market.MF2, product.PF10

TOP 2部分是轻松指定n的地方。 我遇到的问题是,当我在访问中运行它时,它会提示我输入market.MF2的值(我认为这是指子查询中它的实例)。 我认为代码会从主查询中获取每一行的值,但显然它没有这样做。

Tables below:

mMarket

Item_ID     MF2
---------------
1           64
2           28
3           73

mProduct

Item_ID     PF5        PF10
----------------------------
1           2221       Category1
2           6487       Category3
3           73234      Category2
4           76223      Category1
5           99342      Category2

mFact

Market_ID        Product_ID       FF3
--------------------------------------
1                1                1000
1                2                1500
1                3                500
1                4                1000
2                1                1500
2                3                1000
2                5                1500
3                1                1000
3                2                500
3                5                2000

查询有什么问题?我看不到它

提前感谢

预期结果:

If n was 1

MF2        PF10         FF3
----------------------------
64         Category1    2000
28         Category2    2500
73         Category2    2000

If n was 2

MF2        PF10         FF3
----------------------------
64         Category3    1500
28         Category1    1500
73         Category1    1000

2 个答案:

答案 0 :(得分:1)

请看一下这个参考:

仅按市场查询总和:

结果仅按市场总结:

MF2 ITEM_ID PRODUCT_ID  PF5     PF10                                        SUM(F.FF3)
28  2       5,1,3       99342   Category2,Category1,Category2               4000
64  1       3,4,1,2     73234   Category2,Category1,Category1,Category3     4000
73  3       1,2,5       2221    Category1,Category3,Category2               3500

按市场查询总额,类别:

select m.mf2, p.pf10, p.pf5, 
group_concat(f.product_id)as prods, 
m.item_id , sum(f.ff3) as sff
from mmarket m
left join mfact f
on m.item_id = f.market_id
inner join mproduct p
on f.product_id = p.item_id
group by m.mf2, p.pf10
order by sff desc 
;

按市场划分的结果,类别:

MF2     PF10        PF5     PRODS   ITEM_ID     SFF
28      Category2   99342   5,3     2           2500
64      Category1   76223   4,1     1           2000
73      Category2   99342   5       3           2000
28      Category1   2221    1       2           1500
64      Category3   6487    2       1           1500
73      Category1   2221    1       3           1000
64      Category2   73234   3       1           500
73      Category3   6487    2       3           500
根据OP后来的评论

更新的答案

查询:

select x.*
from (
select m.mf2, p.pf10, sum(f.ff3) as sff
from mmarket m
left join mfact f
on m.item_id = f.market_id
inner join mproduct p
on f.product_id = p.item_id
group by m.mf2, p.pf10
  order by sff desc ) as x
limit 1
;

结果:

MF2     PF10          MSFF
28      Category2     2500

基于OP的预期结果 - 更新为符合MS ACCESS SQL

在MYSQL中有很多方法可以实现这一点。但是想给OP获得MS ACCESS的答案。

我建议您将上述结果从** Sum by Market,Category **查询保存到临时表或MS ACCESS查询中。然后在最终查询中使用该查询。

按类别按市场查询排名第一:

-- success final :) by Top 1st
select x.mf2, x.pf10, x.sff
from 
(select m.mf2, p.pf10, p.pf5, 
group_concat(f.product_id)as prods, 
m.item_id , sum(f.ff3) as sff
from mmarket m
left join mfact f
on m.item_id = f.market_id
inner join mproduct p
on f.product_id = p.item_id
group by m.mf2, p.pf10
order by sff desc) as x

where 

(select count(*)
 from
     (select m.mf2, p.pf10, p.pf5, 
      group_concat(f.product_id)as prods, 
      m.item_id , sum(f.ff3) as sff
      from mmarket m
      left join mfact f
      on m.item_id = f.market_id
      inner join mproduct p
      on f.product_id = p.item_id
      group by m.mf2, p.pf10
      order by sff desc) as y

where y.sff >= x.sff
and y.mf2 = x.mf2) =1 //-- Top 3rd, 2nd, 1st
order by x.sff desc
;

按类别排名第一的市场结果:

MF2     PF10    SFF
28  Category2   2500
64  Category1   2000
73  Category2   2000

按类别排名第二的市场结果:

MF2     PF10    SFF
28  Category1   1500
64  Category3   1500
73  Category1   1000

按类别排名第三的市场结果:

MF2     PF10    SFF
64  Category2   500
73  Category3   500

答案 1 :(得分:1)

好的,经过深思熟虑和玩耍后,我找到了一种方法来获得正确的结果。唯一的问题是需要很长时间。我想到了为每个市场设置排名的方法,排名= 1是最大的事实值,2是第二高等等

select StoreCode, Category, Sales, Ranking from 
(
    select main.MF2 as StoreCode, main.PF10 as Category, main.sFF as Sales, 
    (
        select count(*) from
        (
            select market.MF2, product.PF10, sum(fact.FF3) as sFF
            from mMarket market, mProduct product, mFact fact
            where market.Item_ID = fact.Market_ID
            and product.Item_ID = fact.Product_ID
            group by market.MF2, product.PF10
        ) as main2
        where main.MF2 = main2.MF2
        and main2.sFF >= main.sFF
    ) as ranking
    from
    (
        select market.MF2, product.PF10, sum(fact.FF3) as sFF
        from mMarket market, mProduct product, mFact fact
        where market.Item_ID = fact.Market_ID
        and product.Item_ID = fact.Product_ID
        group by market.MF2, product.PF10
    ) as main
}
where ranking = 1
order by 1,2

我知道我应该首先将最内层的查询写入临时表,然后运行此查询,因为需要两次相同的确切查询。 除此之外,如果有人能想出更好的方法来做到这一点或以任何方式加快查询速度。那会很棒:)。

感谢您的帮助,bonCodigo:)