问题
I want to make a SQL query which finds the pname
of parts which are the least repeated in supplier_parts_shipment
.
Table 1 supplier (sno, sname, city)
1, ahmad, jeddah
2,kaled,med
3,njwa,med
Table 2 parts (pno, pname, color)
1, laptop, red
2,keybord,blue
Table 3 supplier_parts_shipment (shno, sno, pno, date)
1,1,1,2014
2,2,1,2014
3,3,2,2014
I tried something like this:
SELECT pname
, min(count(pno))
FROM parts
WHERE pno IN (SELECT pno
FROM supplier_parts_shipment
group by
pname
HAVING min(count(pno))
)
SQL> /
pno IN(SELECT pno FROM supplier_parts_shipment group by pname HAVING min(count(pno))))
*
ERROR at line 2:
ORA-00935: group function is nested too deeply
回答1:
I would have gone about it in a different manner.
First create a query that shows the counts of shipments by pname ordered in ascending values. Use that as a subquery and pick the first.
SELECT * FROM (
SELECT COUNT(sps.pno), p.pname
FROM supplier_parts_shipment sps
JOIN parts p on sps.pno = p.pno
GROUP BY pname
ORDER BY COUNT(sps.pno) ASC)
WHERE ROWNUM = 1
回答2:
If there are multiple parts which are least frequent and you want all of them then:
WITH pno_frequencies AS (
SELECT pno,
COUNT(1) AS pno_cnt
FROM supplier_parts_shipment
GROUP BY pno
),
least_frequent_pnos AS (
SELECT pno
FROM pno_frequencies
WHERE pno_cnt = ( SELECT MIN( pno_cnt ) FROM pno_frequencies )
)
SELECT pname
FROM parts p
WHERE EXISTS (SELECT 1
FROM least_frequent_pnos f
WHERE p.pno = f.pno
);
If you only want a single part regardless of whether there are multiple parts with the same minimum frequency then:
WITH pno_frequencies AS (
SELECT pno,
COUNT(1) AS pno_cnt
FROM supplier_parts_shipment
GROUP BY pno
ORDER BY pno_cnt ASC
),
least_frequent_pno AS (
SELECT pno
FROM pno_frequencies
WHERE ROWNUM = 1
)
SELECT pname
FROM parts p
WHERE EXISTS (SELECT 1
FROM least_frequent_pno f
WHERE p.pno = f.pno
);
SQLFIDDLE
回答3:
min(count(pno))
makes no sense. that is why you are getting the error. try:
select parts.pname
, subse.c
from (select pno
, dense_rank() over (order by c asc) r
, c
from (select pno
, count(pno) as c
from supplier_parts_shipment
group by
pno
)
) subse
inner join parts
on (parts.pno = subse.pno)
where subse.r = 1
the innermost select counts the supplier_parts_shipment for pno, the second level finds the pno that has the least count from the innermost. the outermost select then joins pname from parts and filters to the one that has the least repeats.
来源:https://stackoverflow.com/questions/20035212/sql-group-function-nested-too-deeply