Como selecionar linhas específicas se uma coluna existir ou todas as linhas se uma coluna não existir

23

Estou escrevendo um script que obtém uma contagem de linhas para algumas tabelas, no entanto, para algumas tabelas, quero obter apenas uma contagem de linhas em que um sinalizador está definido (neste caso ativo = 1). Existe uma maneira de fazer isso em uma consulta?

Por exemplo:

A tabela userspossui uma coluna chamada active

A tabela clientsnão possui uma coluna chamada active

Quero obter uma contagem de usuários em que active = 1 e apenas obter uma contagem de clientes.

Antes de você dizer "apenas codificar", esta é uma consulta que está dentro de um script python que pode ser executado em vários bancos de dados diferentes e não tenho como saber quais tabelas meu script selecionará e se elas têm uma coluna chamada activee Eu preferiria ter apenas uma consulta para fazer tudo, em vez de duas separadas, e confiar no mysql para gerar um erro, então sei usar a outra.

Matt S.
fonte
há uma clientid no usuário que faz referência a um cliente
Matt S.

Respostas:

50

Meu primeiro pensamento seria usar o INFORMATION_SCHEMAprimeiro, para que você saiba (em uma consulta para todas as tabelas na instância do MySQL) quais tabelas possuem uma activecoluna e, em seguida, use essas informações para construir suas consultas. E esta é provavelmente a abordagem mais sensata.

Existe uma outra maneira complicada, embora isso funcione, não importa se a tabela possui ou não essa coluna:

SELECT 
  ( SELECT COUNT(*)
    FROM TableName AS t
    WHERE active = 1
  ) AS cnt
FROM
  ( SELECT 1 AS active
  ) AS dummy ;

Testado no SQL-Fiddle Como funciona?

Se a tabela tiver uma coluna denominada active, a consulta será "traduzida" como se tivesse:

    WHERE t.active = 1

Se a tabela não tiver uma coluna chamada active, a consulta será "traduzida" como se tivesse:

    WHERE dummy.active = 1         -- which is true 
ypercubeᵀᴹ
fonte
3

Contagem de clientes por ID do usuário com total geral usando apenas a userstabela:

SELECT
    IFNULL(u.id,'Total') UserID,
    COUNT(u.clientid) ClientCount
FROM users u
WHERE u.active = 1
GROUP BY u.id WITH ROLLUP;

Se a tabela de clientes excluiu registros, faça o seguinte:

SELECT
    IFNULL(u.id,'Total') UserID,
    COUNT(c.id) ClientCount
FROM users u INNER JOIN clients c
ON u.clientid = c.id
WHERE u.active = 1
GROUP BY u.id WITH ROLLUP;

Para userstabelas que não possuem uma activecoluna:

SELECT
    IFNULL(u.id,'Total') UserID,
    COUNT(u.clientid) ClientCount
FROM users u
GROUP BY u.id WITH ROLLUP;

ou

SELECT
    IFNULL(u.id,'Total') UserID,
    COUNT(c.id) ClientCount
FROM users u INNER JOIN clients c
ON u.clientid = c.id
GROUP BY u.id WITH ROLLUP;

Você precisaria executar essas consultas em cada banco de dados e UNION ALLnos resultados.

Se você deseja aproveitar o banco de dados INFORMATION_SCHEMA, aqui está um palpite:

SELECT COUNT(1) INTO @hasactive
FROM information_schema.columns
WHERE table_schema = DATABASE()
AND table_name = 'users'
AND column_name = 'active';
SELECT
    IFNULL(u.id,'Total') UserID,
    COUNT(u.clientid) ClientCount
FROM users u
WHERE IF(@hasactive=1,u.active=1,1)=1
GROUP BY u.id WITH ROLLUP;

De uma chance !!!

RolandoMySQLDBA
fonte
1

Gostaria de complementar a resposta do @ ypercubeᵀᴹ, mas não consigo escrever comentários por causa das restrições.

Se você não souber qual nome da coluna é usado e precisar obter seu valor máximo, poderá fazer isso:

SELECT
    ( SELECT
          max(ISNULL(updateTime, null)) + max(ISNULL(updDT, null))
          FROM tableName as t
    ) AS maxUpdateDT
FROM (SELECT 0 AS updateTime, 0 as updDT) AS dummy;
Dev9
fonte