Secondo i valori massimi e minimi

Data una tabella con più righe di un campo int e lo stesso identificatore, è possibile restituire il 2 ° di massima e di 2 ° valore minimo della tabella.

Una tabella consiste di

ID      |   number
------------------------
1       |     10
1       |     11
1       |     13
1       |     14
1       |     15
1       |     16

Risultato finale sarebbe

ID      |   nMin    |   nMax
--------------------------------
1       |     11    |    15
quale versione di SQL? Un sacco di modi…
2008. meno è meglio… 100s di Milioni di righe
quello che dovrebbe essere il risultato se 2/17 e 2/12 inserimento di righe?
Presumo che la tua domanda è se ci sono solo 2 righe. Idealmente che dovrebbe uscita il 2/12/17. Impressionante domande non avevo pensato che di sicurezza. con 1 riga nMax e nMin dovrebbe = 1 (cioè 2/12/12)

OriginaleL’autore Marty Trenouth | 2011-12-08

6 risposte

  1. 7

    È possibile utilizzare row_number assegnare un punteggio per ogni ID. Poi si può group by id e scegliere per le righe, con la classifica che si sta dopo. L’esempio seguente sceglie il secondo più basso e terzo più alto :

    select  id
    ,       max(case when rnAsc = 2 then number end) as SecondLowest
    ,       max(case when rnDesc = 3 then number end) as ThirdHighest
    from    (
            select  ID
            ,       row_number() over (partition by ID order by number) as rnAsc
            ,       row_number() over (partition by ID order by number desc) as rnDesc
            ) as SubQueryAlias
    group by
            id

    Il max è semplicemente un valore non nullo; si può sostituire con min o anche avg e non influenzare il risultato.

    +1 non riesco a credere che solo 1 su 5 risposte effettivamente gestito questo… e ha permesso per un Id diverso.
    per il secondo punto, perché non solo select X.* from (select row_number() over partition by id order by number) as rn, id, number) X where rn = 2? (E poi la 2°, la più bassa, aggiungere “desc” ordinare?
    L’OP chiede sia in una riga, in modo che la risposta è “pivot” due righe in due colonne
    Questo non dare i giusti risultati. Non 1|11|14 invece di 1|11|15. Dovrebbe essere una semplice modifica, anche se (rnDesc = 2).
    Ha funzionato bene. Sono sicuro che c’è intenzione di ba modifiche qua e là (in realtà sto facendo su un paio di colonne. Anche utilizzando Dense_Rank piuttosto che rowNumber in modo che io possa account per più voci. Grazie mille!

    OriginaleL’autore Andomar

  2. 1

    Questo lavoro, ma vedere avvertenze:

    SELECT Id, number
    INTO #T
    FROM (
      SELECT 1 ID, 10 number
      UNION
      SELECT 1 ID, 10 number
      UNION
      SELECT 1 ID, 11 number
      UNION
      SELECT 1 ID, 13 number
      UNION
      SELECT 1 ID, 14 number
      UNION
      SELECT 1 ID, 15 number
      UNION
      SELECT 1 ID, 16 number
    ) U;
    
    WITH EX AS (
      SELECT Id, MIN(number) MinNumber, MAX(number) MaxNumber
      FROM #T
      GROUP BY Id
    )
    SELECT #T.Id, MIN(number) nMin, MAX(number) nMax
    FROM #T INNER JOIN
         EX ON #T.Id = EX.Id
    WHERE #T.number <> MinNumber AND #T.number <> MaxNumber
    GROUP BY #T.Id
    
    DROP TABLE #T;

    Se si dispone di due MAX valori che sono lo stesso valore, questo non li pick up. Quindi, a seconda di come i dati vengono presentati si potrebbe perdere il risultato corretto.

    lordy che complicato
    Una query per trovare il MIN/MAX, il secondo non li uso 🙂 La merda in alto è solo di installazione, quindi può essere eseguito mediante il copia & incolla, ma sono sicuro che siete consapevoli di questo.
    La mia intenzione era di sottolineare che di self join e gli aggregati sono eccessivo rispetto all’uso di ROW_NUMBER (o DENSE_RANK per comune 2 ° massimo ecc) non è molto più elegante.
    Cordiali saluti, il piano di esecuzione effettivo dimostra che il mio esempio è meglio ottimizzato rispetto all’utilizzo di ROW_NUMBER() utilizzando la risposta fornita da @Andomar.
    In SQL Server 2005 o SQL Server 2008? Aggregati tendono ad essere meglio a ‘2005, funzioni finestra di migliorare con le versioni successive

    OriginaleL’autore Yuck

  3. 1

    Si può selezionare il valore minimo utilizzando il seguente metodo:

    SELECT MAX(Number)
    FROM
    (
      SELECT  top 2 (Number) 
       FROM table1 t1 
       WHERE ID = {MyNumber}
       order by Number
    )a

    Funziona solo se è possibile limitare la query interna con una clausola where

    OriginaleL’autore ccis ccis

  4. 0

    Questo potrebbe essere un modo migliore. Ho rapidamente messo insieme tutto questo, ma se si riesce a combinare le due query, si ottiene esattamente quello che stavi cercando.

    select *
    from
    (
        select
            myID,
            myNumber,
            row_number() over (order by myID) as myRowNumber
        from MyTable
    ) x
    where x.myRowNumber = 2
    
    select *
    from
    (
        select
            myID,
            myNumber,
            row_number() over (order by myID desc) as myRowNumber
        from MyTable
    ) y
    where x.myRowNumber = 2

    OriginaleL’autore Farhan

  5. 0

    lasciate che il nome della tabella essere tblName.
    select max(numero) da tblName cui numero non è in (select max(numero) da tblName);

    stesso per min, basta sostituire max min.

    OriginaleL’autore jht

  6. -1

    Come io ho imparato solo oggi la soluzione è usare LIMITE. Si ordina i risultati in modo che i valori più alti sono in alto e limitare il risultato per 2. Poi si seleziona che subselect ordine e viceversa e di prendere solo il primo.

    SELECT somefield FROM (
    SELECT somefield from table
    ORDER BY somefield DESC LIMIT 2) 
    ORDER BY somefield ASC LIMIT 1
    La domanda è su MSSQL 2K8, che non hanno LIMIT.
    Oh, il commento è stato aggiunto dopo che ho iniziato a scrivere. Merda.

    OriginaleL’autore Angelo Fuchs

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *