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 / 84297
Accepted
IT researcher
IT researcher
Asked: 2014-12-05 04:45:11 +0800 CST2014-12-05 04:45:11 +0800 CST 2014-12-05 04:45:11 +0800 CST

Selecione linhas com o mesmo id, mas nulo e algum outro valor em outra coluna para esse id

  • 772

Eu quero obter apenas linhas com um valor NULLe algum outro valor que não seja NULLpara uma coluna de nome de usuário específica.

Se ambas as linhas tiverem null para esse nome de usuário específico ou ambas tiverem alguns valores diferentes de null, ele não deverá aparecer na saída. Se houver mais de duas linhas para o mesmo nome de usuário com nulo e algum outro valor, elas deverão aparecer.

Abaixo está um exemplo de exemplo e saída. Como isso pode ser feito usando a consulta sql?

+----------+-------+
| username | col2  |
+----------+-------+
| a        | abc   |
| a        | ef    |
| b        | null  |
| b        | null  |
| c        | der   |
| c        | null  |
+----------+-------+

resultado

+----------+------+
| username | col2 |
+----------+------+
| c        | der  |
| c        | null |
+----------+------+
sql-server t-sql
  • 6 6 respostas
  • 53133 Views

6 respostas

  • Voted
  1. Best Answer
    Taryn
    2014-12-05T05:08:48+08:002014-12-05T05:08:48+08:00

    Você deve poder usar a agregação condicional para obter o nome de usuário com um valor col2e null.

    Eu sugiro usar uma cláusula HAVING com as condições. A consulta seria semelhante a:

    select username
    from yourtable
    group by username
    having sum(case when col2 is not null then 1 else 0 end) = 1
      and sum(case when col2 is null then 1 else 0 end) = 1
    

    Consulte SQL Fiddle com demonstração . Essa consulta agrupa seus dados por cada nome de usuário e, em seguida, usa a lógica condicional para verificar se col2atende às duas condições desejadas - onde col2não é nulo e col2 é nulo.

    Você pode usar isso em uma subconsulta, etc., para obter os valores usernamee col2:

    select 
      t.username, 
      t.col2
    from yourtable t
    inner join
    (
      select username
      from yourtable
      group by username
      having sum(case when col2 is not null then 1 else 0 end) = 1
        and sum(case when col2 is null then 1 else 0 end) = 1
    ) d
      on t.username = d.username
    

    Consulte SQL Fiddle com demonstração .

    Se você tiver mais de uma col2linha com ambos nulle outro valor, basta alterar um HAVINGpouco a cláusula:

    select 
      t.username, 
      t.col2
    from yourtable t
    inner join
    (
      select username
      from yourtable
      group by username
      having sum(case when col2 is not null then 1 else 0 end) >= 1
        and sum(case when col2 is null then 1 else 0 end) >= 1
    ) d
      on t.username = d.username;
    

    Veja SQL Fiddle com demonstração

    • 12
  2. Paul White
    2014-12-06T04:45:17+08:002014-12-06T04:45:17+08:00

    Outra solução:

    SELECT Y1.*
    FROM dbo.yourtable AS Y1
    WHERE Y1.username = ANY
    (
        SELECT Y2.username 
        FROM dbo.yourtable AS Y2
        WHERE Y2.col2 IS NULL
        INTERSECT
        SELECT Y3.username 
        FROM dbo.yourtable AS Y3
        WHERE Y3.col2 IS NOT NULL
    );
    

    Plano de execução

    Em uma veia lógica semelhante:

    SELECT Y.* 
    FROM dbo.yourtable AS Y
    WHERE EXISTS
        (
        SELECT * 
        FROM dbo.yourtable AS Y2 
        WHERE Y2.username = Y.username 
        AND Y2.col2 IS NULL
        )
    AND EXISTS
        (
        SELECT * 
        FROM dbo.yourtable AS Y3 
        WHERE Y3.username = Y.username 
        AND Y3.col2 IS NOT NULL
        );
    

    Plano de execução

    Ainda outra:

    SELECT
        SQ1.username,
        SQ1.col2
    FROM 
    (
        SELECT
            Y.username, 
            Y.col2,
            MinCol2 = 
                MIN(CASE WHEN Y.col2 IS NULL THEN -1 ELSE 1 END) 
                OVER (PARTITION BY Y.username), 
            MaxCol2 = 
                MAX(CASE WHEN Y.col2 IS NULL THEN -1 ELSE 1 END) 
                OVER (PARTITION BY Y.username)
        FROM dbo.yourtable AS Y
    ) AS SQ1
    WHERE 
        SQ1.MinCol2 = -SQ1.MaxCol2;
    

    Plano de execução

    • 8
  3. ypercubeᵀᴹ
    2014-12-06T04:45:29+08:002014-12-06T04:45:29+08:00

    Apenas outra maneira de fazer isso:

    ; WITH cte AS
      ( SELECT username, col2,
               cnt_all  = COUNT(*) OVER (PARTITION BY username),
               not_null = COUNT(col2) OVER (PARTITION BY username)
        FROM yourtable AS a
      )
    SELECT username, col2
    FROM cte
    WHERE cnt_all > not_null 
      AND not_null > 0 ;
    
    • 5
  4. JGA
    2014-12-05T05:44:44+08:002014-12-05T05:44:44+08:00

    Este também funciona. Demonstração do SQL Fiddle

    Obtenho C1 como o total de linhas para cada nome de usuário, C2 como o total de linhas nulas para cada nome de usuário e comparo esses valores posteriormente.

    SELECT username, col2 FROM
    (
    SELECT *,
    (SELECT Count(*) FROM T Where username = T1.username) C1,
    (SELECT Count(*) FROM T Where username = T1.username and col2 is null) C2
    FROM T T1
    ) T2
    WHERE C2 > 0 And C1 <> C2
    
    • 4
  5. Bosko
    2014-12-06T06:38:28+08:002014-12-06T06:38:28+08:00

    Eu usaria a subconsulta para selecionar esses nomes de usuário como:

    select username
    from   dbo.yourtable
    group by username
    having sum(distinct case when col2 is not null then 1 else 2 end) = 3;
    
    • 3
  6. ammu
    2014-12-06T08:22:07+08:002014-12-06T08:22:07+08:00

    tentei com esse...

    select a.username from  
    (select username ,col2 
       from yourtable
    where col2 is null) a,(select username ,col2 
                           from yourtable
                            where col2 is not null) b
    where a.username=b.username;
    
    • -1

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

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