2013-04-24 5 views
9

Sono nuovo di Oracle e del mondo SQL. Ho un piccolo problema con una query che non riesco a capire per la vita di me, ho passato alcune ore a provare approcci diversi e non riesco a ottenere il risultato che mi aspetto. Ecco la mia domanda:Come utilizzare MAX() su un risultato di subquery?

SELECT * 
from(Select membership.mem_desc,membership.mem_max_rentals,membership_history.mem_type,  
    count(membership_history.MEM_TYPE) as membership_count 
    from membership_history 
    JOIN membership ON membership.mem_type = membership_history.mem_type 
    group by (membership_history.mem_type,membership.mem_desc,membership.mem_max_rentals) 
    ) g 
WHERE g.membership_count = (select MAX(membership_count) from g); 

Quindi la query interna funziona perfettamente e restituisce due risultati. Ora che ho questi due valori, sto cercando di capire come restituire la riga con il valore massimo di membership_count, che è dove continuo a rimanere bloccato. Nella query sopra ho provato a usare MAX() nella clausola where, ma all'interno di quella selezione continuo a ricevere l'errore 'table not found' (che significa 'g'). Quindi la mia domanda è: come posso usare la funzione MAX() sui risultati della mia subquery? Qualsiasi pensiero o suggerimento sarebbe molto apprezzato !!!!!

+0

Se non si è a conoscenza, [sqlfiddle] (http://www.sqlfiddle.com) ha Oracle disponibile e si può giocare con vari formati di istruzioni. – hd1

risposta

0

Si potrebbe provare qualcosa di simile

SELECT membership.mem_desc,membership.mem_max_rentals,membership_history.mem_type, membership_count, rank() over ORDER BY membership_count DESC as ranky 
from 
(Select membership.mem_desc,membership.mem_max_rentals,membership_history.mem_type,  
count(membership_history.MEM_TYPE) as membership_count 
from membership_history 
JOIN membership ON membership.mem_type = membership_history.mem_type 
group by (membership_history.mem_type,membership.mem_desc,membership.mem_max_rentals) 
) 
WHERE ranky =1; 
10

Non è necessario il subquery che trova il valore massimo.
Invece,; è sufficiente il primo fila dopo aver ordinato le righe:

select * from (
    select 
    membership.mem_desc, 
    membership.mem_max_rentals, 
    membership_history.mem_type,  
    count(membership_history.MEM_TYPE) as membership_count 
    from membership_history 
    JOIN membership ON membership.mem_type = membership_history.mem_type 
    group by (membership_history.mem_type,membership.mem_desc,membership.mem_max_rentals) 
    ORDER BY 4 DESC -- Added this line 
) g 
WHERE ROWNUM = 1. -- Added this line 
0

non è possibile utilizzare una tabella derivata direttamente nella clausola in cui darà table or view does not exist errore in modo da ottenere il valore di conteggio massimo è possibile utilizzare HAVING clausola o Analytical Functions o Rownum come

select * from 
     (Select membership.mem_desc,membership.mem_max_rentals,membership_history.mem_type,  
     count(membership_history.MEM_TYPE) as membership_count 
     from membership_history a 
     JOIN membership b ON b.mem_type = a.mem_type 
     group by (membership_history.mem_type,membership.mem_desc,membership.mem_max_rentals) 
     having count(a.MEM_TYPE) = (Select  
     MAX(count(a.MEM_TYPE)) from membership_history a 
     JOIN membership b ON b.mem_type = a.mem_type 
     group by (a.mem_type,b.mem_desc,b.mem_max_rentals))); 

(OR)

.210

(OR)

select * from 
(SELECT g.*,rownum rn from 
     (Select membership.mem_desc,membership.mem_max_rentals,membership_history.mem_type,  
     count(membership_history.MEM_TYPE) as membership_count 
     from membership_history 
     JOIN membership ON membership.mem_type = membership_history.mem_type 
     group by (membership_history.mem_type,membership.mem_desc,membership.mem_max_rentals) 
     order by membership_count desc) g) 
WHERE rn=1; 
3

Questo è tutto buono SQL.

Il modo migliore per trovare un valore di colonna utilizzando il valore della colonna chiave primaria Max è:

SELECT .... from tablename 
WHERE ... AND 
    (SELECT max(primary key name) FROM tablename WHERE ....) = primary_key_name 

questo esempio restituirà un valore scalare.

0

Penso che la soluzione più pulita sia utilizzare la condizione di confronto ALL. Viene utilizzato per confrontare un valore con un elenco o sottoquery.

SELECT 
    m.mem_desc, 
    m.mem_max_rentals, 
    mh.mem_type,  
    COUNT(mh.mem_type) as membership_count 
FROM membership_history mh 
JOIN membership m ON m.mem_type = mh.mem_type 
GROUP BY mh.mem_type,m.mem_desc,m.mem_max_rentals 
HAVING membership_count >= ALL (
    SELECT count(*) 
    FROM membership_history 
    GROUP BY mem_type 
)