Domanda

Ho questa istruzione SQL:

SELECT * FROM converts 
WHERE email='myemail@googlemail.com' AND status!='1' 
ORDER BY date ASC, priority DESC

Questo ordina solo per data ma voglio dare la mia colonna "priorità" più autorità. Come posso fare questo?

Dovrebbe ordinare prima per data, ma se il tempo tra due record è di 10 minuti, voglio che la priorità prenda il sopravvento. Come posso fare questo nella mia istruzione SQL o deve essere nella mia logica dell'applicazione? Speravo di poterlo fare nella mia istruzione SQL.

Grazie a tutti per l'aiuto

È stato utile?

Soluzione

Potresti quantizzare l'ordinamento 'data' in blocchi di 10 minuti, quindi che ne dici di ordinare per piano (unix_timestamp (data) / 600), e quindi per priorità

SELECT * FROM converts 
WHERE email='myemail@googlemail.com' AND status!='1' 
ORDER BY floor(unix_timestamp(date)/600) ASC, priority DESC

Sebbene due date possano essere comunque distanti meno di 10 minuti l'una dall'altra, ma a cavallo tra due diversi pezzi da 10 minuti ". Forse è sufficiente, ma penso che fare esattamente ciò che richiedi venga fatto meglio dall'applicazione.

(OP ha richiesto una spiegazione estesa ....)

Prendi due volte a cavallo di un confine di dieci minuti, come 9:09 e 9:11 oggi:

  • floor (unix_timestamp ('2009-03-16 09: 09 : 00') / 600) = 2061990
  • floor (unix_timestamp ('2009-03-16 09: 11 : 00') / 600) = 2061991

Supponi di avere una riga con priorità più alta per 09:11 rispetto alle 09:09 - apparirà comunque dopo la riga 09:09 perché è caduta nel blocco successivo di 10 minuti, anche se era solo 2 minuti diversi.

Quindi questo approccio è un'approssimazione, ma non risolve il problema come indicato in origine.

Nel modo in cui hai dichiarato il tuo problema, una riga con priorità alta potrebbe apparire prima di una registrata diverse ore (o giorni o mesi!) prima, a condizione che ci fosse una serie ininterrotta di riga con priorità inferiore con un intervallo inferiore a 10 minuti.

Altri suggerimenti

Un'altra variante sarebbe:

SELECT * FROM converts 
WHERE email='myemail@googlemail.com' AND status!='1' 
ORDER BY (unix_timestamp(date)/60) - priority 

Ancora non esattamente quello che hai richiesto, ma abbastanza vicino.

Supponendo che tu abbia realmente inteso " il tempo tra due dischi è di 10 minuti [o meno], quindi voglio che la priorità prenda il sopravvento?

quindi ordina solo per blocchi di dieci minuti, quindi per priorità ...

Seleziona ...
Ordina per dataDiff (min, 0, data) / 10, priorità

puoi regolare il valore 0 per controllare dove ogni "blocco di minuti" inizia e si ferma ... Se MySql non ha una funzione DateDiff, usa qualunque espressione in MySQL che fornisca un conteggio dei minuti da qualche tempo di riferimento ...

Se si utilizza SQL Server 2005/2008, è possibile eseguire questa attività con un CTE ricorsivo. Nota che ho scritto questo testo nel blocco note e non è stato ancora testato. Quando avrò la possibilità di testare i risultati della query, aggiornerò il CTE in caso di errore o rimuoverò del tutto il commento.

WITH date_cte

AS

(SELECT *
    , 'sequential_order' = ROW_NUMBER() OVER
        (PARTITION BY email
        ORDER BY date ASC, priority DESC)
FROM converts
WHERE email = 'myemail@googlemail.com'
AND status <> '1')

, recursive_date_cte

AS

(SELECT dc1.*
    , 'sort_level' = 1
FROM date_cte dc1
WHERE sequential_order = 1
UNION
SELECT dc1.*
    , 'sort_level' = CASE
        WHEN DATEDIFF(MINUTE, dc1.date, dc2.date) <= 10 THEN sort_level
        ELSE sort_level + 1 END
LEFT JOIN date_cte dc2
    ON dc1.sequential_order = dc2.sequential_order - 1
WHERE dc1.sequential_order > 1)

SELEZIONA *

FROM recursive_date_cte

ORDINA PER sort_level ASC

, priority DESC

basta cambiare l'ordine o le colonne nell'istruzione dell'ordine

SELECT * FROM converts WHERE email='myemail@googlemail.com' AND status!='1' ORDER BY priority DESC, date ASC
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top