我有一张大表Audit
,其中包含数千条拒绝声明的记录。每个人都来自供应商,并有拒绝理由和地位。只有id
是唯一的。
id | denial | supplier | status
---|------------------|---------------|---------
1 | Duplicate claim | ACME | Adjusted
2 | Not authorized | Umbrella Corp | Adjusted
3 | Not authorized | Stark Ind. | Adjusted
4 | Rec'd after due | ACME | Override
5 | Duplicate claim | Stark Ind. | Adjusted
... etc
我需要的是按记录计数“调整”状态声明的前5个拒绝原因,以及每个拒绝原因的记录计数的最高提供者。
denial | cnt_denial | top_supplier | cnt_top_supplier
----------------|------------|---------------|-----------------
Not authorized | 917 | Stark Ind. | 351
Duplicate claim | 685 | Stark Ind. | 195
Not in contract | 525 | ACME | 216
Rec'd after due | 512 | Umbrella Corp | 500
Explosions | 349 | ACME | 231
我尝试了很多方法,主要是尝试调整其他类似的解决方案,但是我在这里超越了我微薄的SQL知识而感到沮丧。我尝试过的几种解决方案在MS Access(2010)中不起作用。我创建了两个查询作为开始,但是我无法以我需要的方式加入它们。
此查询完全返回我需要的拒绝原因数据:
SELECT TOP 5 denial, Count(*) AS cnt_denial
FROM Audit
GROUP BY status, denial
HAVING status="Adjusted"
ORDER BY Count(*) DESC;
此查询包含表中每个拒绝/供应商分组的计数。我不确定如何获得每个拒绝原因的顶级供应商,这似乎应该很简单,但我遇到了麻烦。编辑:这是我的主要问题。如果我能够获得每个拒绝原因的顶级单一供应商,我可以找出加入。我尝试过使用MAX但还没有成功。 / EDIT
SELECT denial, supplier, Count(*) AS cnt_supplier
FROM Audit
GROUP BY denial, supplier, status
HAVING status="Adjusted"
ORDER BY Count(*) DESC;
我需要一个查询,因为我只是通过ADO从Excel传递此信息。任何帮助都将非常感激。
答案 0 :(得分:1)
我不知道这是否是完全有效的Access SQL。如果不是这样的话,它不需要太多调整:
select
d.denial,
d.cnt_denial,
ds.supplier as top_supplier,
ds.cnt_supplier as cnt_top_supplier
from
(
select top 5 denial, count(*) as cnt_denial
from Audit
where status = 'Adjusted'
group by denial
order by count(*) desc
) d
inner join
(
select denial, supplier, count(*) as cnt_supplier
from Audit
where status = 'Adjusted'
group by denial, supplier
) ds
on ds.denial = d.denial
where not exists (
select 1
from Audit as a2
where a2.status = 'Adjusted'
and a2.denial = ds.denial and a2.supplier <> ds.supplier
group by a2.supplier
having count(*) > ds.cnt_supplier
/* or count(*) = ds.cnt_supplier and a2.supplier < ds.supplier -- tiebreaker */
)
order by d.cnt_denial desc, ds.supplier
通过使用top 5
,无论关系如何,它都只抓取五行。然后使用子查询处理每个组的前1个,在这种情况下,您将包含tie并可能在最终结果中检索超过5行。如果您需要或在供应商排名中打破关系并将其排除,那么在拒绝级别包含关系并不太困难。
编辑:我将一些测试数据汇总在一起,并且打破平局似乎可以在SQL Server上运行。 http://rextester.com/ZEWJ43486
答案 1 :(得分:0)
看起来你已经完成了所有艰苦的工作。
一种解决方案是在第二个查询中测试拒绝原因包含
将您的第一个查询保存为 qTop5Reasons
SELECT TOP 5 denial, Count(*) AS cnt_denial
FROM Audit
GROUP BY status, denial
HAVING status="Adjusted"
ORDER BY Count(*) DESC;
根据该查询中的原因修改您的第二个查询以限制结果:
SELECT Audit.denial, Audit.supplier, Count(*) AS cnt_supplier
FROM Audit
WHERE (Audit.denial In (SELECT denial FROM qTop5Reasons))
GROUP BY Audit.denial, Audit.supplier, Audit.status
HAVING (((Audit.[status])="Adjusted"))
ORDER BY Count(*) DESC;
答案 2 :(得分:0)
你应该尝试内联。试试这个
SELECT A.DENIAL, A.Cnt_Denial,B.Supplier as TOP_SUPPLIER, B.Cnt_supplier as
TOP_CNT_SUPPLIER
FROM
(SELECT TOP 5 denial, Count(*) AS cnt_denial
FROM Audit
GROUP BY status, denial
HAVING status="Adjusted"
ORDER BY Count(*) DESC) AS A INNER JOIN
(SELECT TOP 5 denial, supplier, Count(*) AS cnt_supplier
FROM Audit
GROUP BY denial, supplier, status
HAVING status="Adjusted"
ORDER BY Count(*) DESC) AS B
ON A.DENIAL = B.DENIAL