SQL, Order by - Como dar mais autoridade a outras colunas?
-
22-07-2019 - |
Pergunta
Eu tenho esta declaração SQL:
SELECT * FROM converts
WHERE email='myemail@googlemail.com' AND status!='1'
ORDER BY date ASC, priority DESC
Isso apenas ordena por data, mas quero dar à minha coluna "prioridade" mais autoridade. Como posso fazer isso?
Ele deve encomendar por data primeiro, mas se a hora entre dois registros for 10 mintas, eu quero que a prioridade assuma. Como posso fazer isso na minha instrução SQL ou isso precisa estar na minha lógica de aplicativo? Eu esperava poder fazer isso na minha declaração SQL.
Obrigado a todos por qualquer ajuda
Solução
Você pode quantizar o pedido de 'data' em pedaços de 10 minutos, então que tal pedidos por piso (unix_timestamp (data)/600) e depois por prioridade
SELECT * FROM converts
WHERE email='myemail@googlemail.com' AND status!='1'
ORDER BY floor(unix_timestamp(date)/600) ASC, priority DESC
Embora duas datas ainda possam estar a menos de 10 minutos de distância, mas abordam dois "pedaços" diferentes de 10 minutos. Talvez isso seja suficiente, mas acho que fazer exatamente o que você solicita é melhor feito pelo aplicativo.
(OP solicitado explicação expandida ....)
Tome duas vezes que atravessam um limite de dez minutos, como 9:09 e 9:11 hoje:
- Floor (Unix_timestamp ('2009-03-16 09:09:00')/600) = 2061990
- Floor (Unix_timestamp ('2009-03-16 09:11:00')/600) = 2061991
Suponha que você tenha uma fila de prioridade mais alta para 09:11 do que 09:09 - ainda aparecerá depois A linha das 09:09 porque caiu no próximo pedaço de 10 minutos, apesar de ter sido apenas 2 minutos diferentes.
Portanto, essa abordagem é uma aproximação, mas não resolve o problema como declarado originalmente.
Da maneira como você declarou seu problema, uma linha de alta prioridade pode aparecer antes de uma gravação várias horas (ou dias ou meses!) Anteriormente, desde que houvesse uma série ininterrupta de fila de prioridade mais baixa com um intervalo inferior a 10 minutos.
Outras dicas
Outra variação seria:
SELECT * FROM converts
WHERE email='myemail@googlemail.com' AND status!='1'
ORDER BY (unix_timestamp(date)/60) - priority
Ainda não é exatamente o que você exigiu, mas bem perto.
Supondo que você realmente quis dizer "o tempo entre dois registros é 10 minutos [ou menos], então eu quero que a prioridade assuma?
Em seguida, basta classificar por dez minutos e depois por prioridade ...
Selecione ...
Ordem por Datediff (min, 0, data) / 10, prioridade
Você pode ajustar o valor 0 para controlar onde cada um "bloco de minuto" começa e para ... se o MySQL não tiver uma função datediff, use qualquer expressão em MySQL que forneça uma contagem de minutos desde algum tempo de referência ...
Se você estiver usando o SQL Server 2005/2008, você pode realizar essa tarefa com um CTE recursivo. Observe que escrevi este texto no bloco de notas e ele ainda não foi testado. Depois de ter a chance de testar os resultados da consulta, atualizarei o CTE se houver um erro ou remover esse comentário.
Com date_cte
COMO
(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
COMO
(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)
Selecione *
De recursive_date_cte
Ordem por Sort_level ASC
, priority DESC
Basta mudar a ordem ou os colums na declaração do pedido
SELECT * FROM converts WHERE email='myemail@googlemail.com' AND status!='1' ORDER BY priority DESC, date ASC