2012-04-19 7 views
6

Quindi penso di aver visto una soluzione a questo, ma sono tutte domande molto complicate. Sono in oracolo 11g come riferimento.Come limitare il numero di righe restituite da questo LEFT JOIN a uno?

Quello che ho è un semplice collegamento a molti che funziona benissimo ma non ho bisogno di molti. Voglio solo la tabella di sinistra (quella) per unire qualsiasi riga 1 che soddisfi i criteri di join ... non molte righe.

Ho bisogno di fare questo perché la query è in un rollup che conta quindi se faccio il normale LEFT JOIN ottengo 5 righe in cui ho solo dovrei ottenere 1.

Così esempio dati è la seguente:

TABLE 1: 
------------- 
TICKET_ID  ASSIGNMENT 
5    team1 
6    team2 

TABLE 2: 
------------- 
MANAGER_NAME ASSIGNMENT_GROUP USER 
joe   team1    sally 
joe   team1    stephen 
joe   team1    louis 
harry   team2    ted 
harry   team2    thelma 

quello che devo fare è unire queste due tabelle su ASSIGNMENT = ASSIGNMENT_GROUP ma avere solo 1 riga restituita.

quando faccio un LEFT JOIN ottengo tre righe restituite beaucse che è la natura di HTE LEFT JOIN

+3

Perché questo tag è MySQL? –

+2

Sebbene ci siano molte risposte pubblicate, è impossibile sapere cosa è necessario se non si spiega perché si desidera solo 1 riga. Vuoi davvero un utente casuale per assignment_group? Per che cosa? – winkbrace

risposta

7

Se Oracle supporta numero di riga (partizione) è possibile creare una selezione sub query in cui fila è uguale a 1.

SELECT * FROM table1 
LEFT JOIN 
(SELECT * 
FROM (SELECT *, 
      ROW_NUMBER() 
      OVER(PARTITION BY assignmentgroup ORDER BY assignmentgroup) AS Seq 
    FROM table2) a 
WHERE Seq = 1) v 
ON assignmet = v.assignmentgroup 
+0

potresti pubblicare un'istruzione SQL di esempio basata sulla query di abover. So che puoi fare una sottoquery semplicemente non sono sicuro della sintassi. – BostonMacOSX

+3

non è così facile da toccare su un telefono ... –

1

Penso che quello che è necessario è quello di utilizzare GROUP BY sul campo ASSIGNMENT_GROUP.

http://www.w3schools.com/sql/sql_groupby.asp

+0

Non credo che otterrà ciò che voglio perché ho bisogno anche delle altre informazioni negli altri campi. Dovrei fare cose strane come concatenarle. – BostonMacOSX

-3

è possibile utilizzare subquery - selezionare top 1

+1

che funziona solo per SQL Server –

+0

utilizzare il limite 1 quindi. Nessun grosso problema. – ZERO

+3

Oracle inoltre non supporta la clausola 'LIMIT'. –

1

In Oracle, se si desidera 1 risultato, è possibile utilizzare l'istruzione ROWNUM per ottenere i primi valori N di una query, ad esempio:

SELECT * 
FROM TABLEX 
WHERE 
ROWNUM = 1 --gets the first value of the result 

Il problema con questa singola query è che Oracle non restituisce mai i dati nello stesso ordine. Quindi, è necessario oder i dati prima dell'uso rownum:

SELECT * 
FROM 
    (SELECT * FROM TABLEX ORDER BY COL1) 
WHERE 
ROWNUM = 1 

Per il vostro caso, sembra necessario solo 1 risultato, quindi la query dovrebbe essere simile:

SELECT * 
FROM 
    TABLE1 T1 
    LEFT JOIN 
    (SELECT * 
    FROM TABLE2 T2 WHERE T1.ASSIGNMENT = T2.ASSIGNMENT_GROUP 
    AND 
    ROWNUM = 1) T3 ON T1.ASSIGNMENT = T3.ASSIGNMENT_GROUP 
+0

non mi limiterà a 1 riga dal tavolo 1 pure? Ho bisogno solo di 1 riga dalla tabella di join 2 ciascuna ma tutte le righe della tabella 1. – BostonMacOSX

+0

@BostonMacOSX Ho già modificato la mia risposta –

+1

Non è possibile fare riferimento a 'T1.ASSIGNMENT' come nella vista in linea poiché' T1' è definito in un livello più alto della query. È possibile aggiungere una funzione analitica partizioni di 'T2.ASSIGNMENT_GROUP' e quindi includere il rango nei criteri di join (un esempio di ciò è riportato di seguito). Oppure puoi spostare la query su 'T2' in una subquery scalare nella tua lista' SELECT', anche se potrebbe essere molto meno efficiente. –

0

In MySQL si può solo GRUPPO PER ASSEGNAZIONE e sii fatto. Oracle è più severo e si rifiuta di scegliere (in modo indefinito) quali valori delle tre righe scegliere. Ciò significa che tutte le colonne restituite devono essere parte di GROUP BY o essere soggette a una funzione di aggregazione (COUNT, MIN, MAX ...)

Puoi ovviamente scegliere di non preoccuparti e utilizzare alcune funzioni di aggregazione su le colonne restituite.

select TICKET_ID, ASSIGNMENT, MAX(MANAGER_NAME), MAX(USER) 
from T1 
left join T2 on T1.ASSIGNMENT=T2.ASSIGNMENT_GROUP 
group by TICKET_ID, ASSIGNMENT 

Se lo fai, dubito seriamente che tu abbia bisogno del JOIN in primo luogo.

MySQL può anche essere d'aiuto con GROUP_CONCAT nel caso in cui si desideri una concatenazione di stringhe di valori di gruppo per una colonna (gli utenti spesso si comportano così), ma con Oracle che è staggeringly complex.

L'utilizzo di una sottoquery come già suggerito è un'opzione, look here per un esempio. Consente inoltre di ordinare la sottoquery prima di selezionare la riga superiore.

+0

Questa domanda riguarda Oracle, quindi tutte le cose che puoi fare in un db differente non sono importanti – Forage

5

Si potrebbe fare qualcosa di simile.

SELECT t1.ticket_id, 
     t1.assignment, 
     t2.manager_name, 
     t2.user 
    FROM table1 t1 
     LEFT OUTER JOIN (SELECT manager_name, 
           assignment_group, 
           user, 
           row_number() over (partition by assignment_group 
                --order by <<something>> 
               ) rnk 
          FROM table2) t2 
        ON ( t1.assignment = t2.assignment_group 
         AND t2.rnk = 1) 

Questo partizioni i dati in table2 da assignment_group e poi arbitrariamente loro ranghi per tirare una riga arbitraria per assignment_group. Se ti interessa quale riga viene restituita (o se vuoi rendere deterministica la riga), puoi aggiungere una clausola ORDER BY alla funzione di analisi.

+0

Puoi aggiungere (magari commentato sulla sua stessa riga) la clausola order by –

+1

@RuneJeppesen - Aggiunto un esempio di ' ordina per'. –