Cómo seleccionar filas específicas si existe una columna o todas las filas si no existe una columna

23

Estoy escribiendo un script que obtiene un recuento de filas para algunas tablas, sin embargo, para algunas tablas solo quiero obtener un recuento de filas donde se establece un indicador (en este caso activo = 1). ¿Hay alguna manera de hacer esto en una consulta?

P.ej:

La tabla userstiene una columna llamada activa

La tabla clientsno tiene una columna llamada activa

Quiero obtener un recuento de usuarios donde active = 1 y solo obtener un recuento de clientes.

Antes de decir "solo codifíquelo", esta es una consulta que va dentro de un script de Python que podría ejecutarse en numerosas bases de datos diferentes y no tengo forma de saber qué tablas seleccionará mi script y si tienen una columna llamada active, y Preferiría tener solo una consulta para hacerlo todo en lugar de dos separadas y confiar en mysql para arrojar un error, así que sé usar la otra.

Matt S.
fuente
hay un ID de cliente en el usuario que hace referencia a un cliente
Matt S.

Respuestas:

50

Mi primer pensamiento sería usar el INFORMATION_SCHEMAprimero, para que pueda saber (en una consulta para todas las tablas en la instancia de MySQL) qué tablas tienen una activecolumna y luego usar esa información para construir sus consultas. Y este es probablemente el enfoque más sensato.

Sin embargo, hay otra forma complicada que funciona sin importar si la tabla tiene o no una columna de este tipo:

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

Probado en SQL-Fiddle ¿Cómo funciona?

Si la tabla tiene una columna llamada active, la consulta se "traduce" como si tuviera:

    WHERE t.active = 1

Si la tabla no tiene una columna llamada active, la consulta se "traduce" como si tuviera:

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

Recuento de clientes por ID de usuario con Gran total utilizando solo la userstabla:

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

Si la tabla de clientes ha eliminado registros, haga esto:

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 userstablas que no tienen una activecolumna:

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

o

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;

Debería ejecutar estas consultas en cada base de datos y UNION ALLlos resultados.

Si desea aprovechar la base de datos INFORMATION_SCHEMA, aquí hay una conjetura:

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;

Darle una oportunidad !!!

RolandoMySQLDBA
fuente
1

Me gustaría complementar la respuesta de @ ypercubeᵀᴹ, pero no puedo escribir comentarios debido a las restricciones.

Si no sabe qué nombre de columna se usa y necesita obtener su valor máximo, puede hacerlo:

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
fuente