AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 177749
Accepted
Randomize
Randomize
Asked: 2017-07-02 02:17:38 +0800 CST2017-07-02 02:17:38 +0800 CST 2017-07-02 02:17:38 +0800 CST

Como mover valores não nulos classificados em ordem alfabética no MySQL?

  • 772

Tenho uma tabela assim:

   |Name1 |Name2 | Name3 | Name4|
   |------+------+-------+------|
   |Zoe   |NULL  |NULL   |NULL  |
   |Julia |NULL  |NULL   |NULL  |
   |NULL  |Ashley|NULL   |NULL  |
   |NULL  |Belvet|NULL   |NULL  |
   |NULL  |Maria |NULL   |NULL  |
   |NULL  |NULL  |Mark   |NULL  |
   |NULL  |NULL  |Jane   |NULL  |
   |NULL  |NULL  |NULL   |Eve   |
   |NULL  |NULL  |NULL   |Jenny |
   |NULL  |NULL  |NULL   |Ketty |

Como posso ordenar em ordem alfabética cada coluna de forma que os valores NULL sejam colocados na parte inferior, assim:

   |Name1 |Name2 | Name3 | Name4|
   |------+------+-------+------|
   |Julia |Ashley|Jane   |Eve   |
   |Zoe   |Belvet|Mark   |Jenny |
   |NULL  |Maria |NULL   |Ketty |

?

mysql order-by
  • 1 1 respostas
  • 161 Views

1 respostas

  • Voted
  1. Best Answer
    joanolo
    2017-07-02T03:27:56+08:002017-07-02T03:27:56+08:00

    O que você parece querer é algo bastante incomum (pelo menos na minha perspectiva), onde o conceito de linha não é mais importante, e você se preocupa apenas com colunas , ignorando de qual linha seus valores vieram. Isso é um pouco complicado, porque o SQL entende colunas junto com linhas. Então você precisa, de alguma forma, desconstruir suas tabelas e reconstruí -las mais tarde.

    A primeira coisa que faremos é ter um diferente table(resultado de uma subconsulta) com duas colunas: a row_number()e one NameX:

    Para cada coluna, faremos algo como:

    -- First column
    SELECT 
         @rownum := @rownum + 1 AS rank,
         Name1
    FROM 
        t,  (SELECT @rownum := 0) r
    ORDER BY
        -- 'zzzzzzz' = value larger than any realistically one
        -- in column Name1. Change if necessary.
        COALESCE(Name1, 'zzzzzzzzzz'),
    

    ... e isso resultaria em:

    classificação | Nome1
    ---: | :----
       1 | Júlia
       2 | Zoe  
       3 | nulo  
       4 | nulo  
       5 | nulo  
       6 | nulo  
       7 | nulo  
       8 | nulo  
       9 | nulo  
      10 | nulo 
    

    Esta é uma desconstrução (para colocar um nome).


    NOTA : @rownum := @rownum + 1é equivalente a usar ROW_NUMBER()no SQL padrão. Veja ROW_NUMBER() no MySQL . MySQL não tem uma row_number()função, mas permite que você use variáveis ​​em suas consultas (Veja MySQL 5.7 Reference Manual / Language Structure / User-Defined Variables / 9.4 User-Defined Variables )


    Com isso em mente, devemos então fazer:

    1. Repita 4 vezes, para Name1 .. Name4, para obter na verdade 4 tabelas (virtuais). Na verdade, teremos desconstruído a tabela original.
    2. Temos agora 4 tabelas (virtuais) com uma coluna comum ( rank) e com o mesmo número de linhas da tabela original. Nós JOINos reunimos nesta coluna comum.
    3. Nós nos livramos das linhas que são NULLde ponta a ponta adicionando umWHERE NOT (Name1 IS NULL AND Name2 IS NULL AND Name3 IS NULL AND Name4 IS NULL)

    A consulta completa será então:

    SELECT
        Name1, Name2, Name3, Name4
    FROM
        (SELECT   @rownum1 := @rownum1 + 1 AS rank, Name1
        FROM      t, (SELECT @rownum1 := 0) AS r1
        ORDER BY  coalesce(Name1, 'zzzzzzzzz')
        )  c1
        JOIN
        (SELECT   @rownum2 := @rownum2 + 1 AS rank, Name2
        FROM      t, (SELECT @rownum2 := 0) AS r2
        ORDER BY  coalesce(Name2, 'zzzzzzzzz')
        )  c2
        ON c2.rank = c1.rank
        JOIN
        (SELECT   @rownum3 := @rownum3 + 1 AS rank, Name3
        FROM      t, (SELECT @rownum3 := 0) AS r3
        ORDER BY  coalesce(Name3, 'zzzzzzzzz')
        )  c3
        ON c3.rank = c1.rank
        JOIN
        (SELECT   @rownum4 := @rownum4 + 1 AS rank, Name4
        FROM      t, (SELECT @rownum4 := 0) AS r4
        ORDER BY  coalesce(Name4, 'zzzzzzzzz')
        )  c4
        ON c4.rank = c1.rank
    WHERE
        NOT (Name1 IS NULL AND Name2 IS NULL AND Name3 IS NULL AND Name4 IS NULL)
    

    E isso lhe dará o resultado pretendido:

    Nome1 | Nome2 | Nome3 | Nome4
    :---- | :----- | :---- | :----
    Júlia | Ashley | Jane | Véspera  
    Zoe | Belvet | Marcar | Jenny
    nulo   | Maria | nulo   | Ketty
    

    Você pode verificar tudo junto no dbfiddle aqui


    Se você estiver usando o MariaDB 10.2 ou outro banco de dados que conheça WINDOWfunções, você pode simplificar esta consulta para:

    SELECT
        Name1, Name2, Name3, Name4
    FROM
        (SELECT Name1, row_number() over (order by coalesce(Name1, 'zzzzzzzzz')) AS rank
        FROM t
        )  c1
        JOIN
        (SELECT Name2, row_number() over (order by coalesce(Name2, 'zzzzzzzzz')) AS rank
        FROM t
        )  c2
        ON c2.rank = c1.rank
        JOIN
        (SELECT Name3, row_number() over (order by coalesce(Name3, 'zzzzzzzzz')) AS rank
        FROM t
        )  c3
        ON c3.rank = c1.rank
        JOIN
        (SELECT Name4, row_number() over (order by coalesce(Name4, 'zzzzzzzzz')) AS rank
        FROM t
        )  c4
        ON c4.rank = c1.rank
    WHERE
        NOT (Name1 IS NULL AND Name2 IS NULL AND Name3 IS NULL AND Name4 IS NULL)
    

    e você obterá o mesmo resultado.

    dbfiddle aqui


    Você pode até tirar vantagem do fato de que o MariaDB classifica NULLS LASTe ignorar o COALESCE:

    SELECT
        Name1, Name2, Name3, Name4
    FROM
        (SELECT Name1, row_number() over (order by Name1) AS rank
        FROM t
        )  c1
        JOIN
        (SELECT Name2, row_number() over (order by Name2) AS rank
        FROM t
        )  c2
        ON c2.rank = c1.rank
        JOIN
        (SELECT Name3, row_number() over (order by Name3) AS rank
        FROM t
        )  c3
        ON c3.rank = c1.rank
        JOIN
        (SELECT Name4, row_number() over (order by Name4) AS rank
        FROM t
        )  c4
        ON c4.rank = c1.rank
    WHERE
        NOT (Name1 IS NULL AND Name2 IS NULL AND Name3 IS NULL AND Name4 IS NULL);
    

    dbfiddle aqui

    NOTA: Os planos de execução são idênticos, portanto, espera-se que as duas últimas consultas demorem aproximadamente o mesmo tempo para serem executadas.

    • 0

relate perguntas

  • Existem ferramentas de benchmarking do MySQL? [fechado]

  • Onde posso encontrar o log lento do mysql?

  • Como posso otimizar um mysqldump de um banco de dados grande?

  • Quando é o momento certo para usar o MariaDB em vez do MySQL e por quê?

  • Como um grupo pode rastrear alterações no esquema do banco de dados?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve