Как выбрать определенные строки, если столбец существует, или все строки, если столбец не существует

23

Я пишу сценарий, который получает количество строк для нескольких таблиц, однако для некоторых таблиц я хочу получить только количество строк, в которых установлен флаг (в данном случае active = 1). Есть ли способ сделать это в одном запросе?

Например:

Таблица usersимеет столбец с именем active

В таблице clientsнет столбца с именем active

Я хочу получить количество пользователей, где active = 1, и просто получить количество клиентов.

Прежде чем сказать «просто жестко запрограммировать его», это запрос, который выполняется внутри скрипта Python, который может быть запущен в многочисленных различных базах данных, и у меня нет никакого способа узнать, какие таблицы будет выбирать мой скрипт, и если у них есть столбец с именем active, и Я предпочел бы иметь только один запрос, чтобы сделать все это вместо двух отдельных и полагаться на mysql, чтобы выдать ошибку, поэтому я знаю, чтобы использовать другой.

Мэтт С.
источник
в клиенте есть клиент, который ссылается на клиента
Мэтт С.

Ответы:

50

Моей первой мыслью было бы использовать INFORMATION_SCHEMAпервое, чтобы вы узнали (в одном запросе для всех таблиц в экземпляре MySQL), какие таблицы имеют activeстолбец, а затем использовали эту информацию для построения ваших запросов. И это, наверное, самый вменяемый подход.

Есть еще один хитрый способ, который работает независимо от того, есть ли в таблице такой столбец или нет:

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

Проверено на SQL-Fiddle Как это работает?

Если в таблице есть столбец с именем active, запрос «переводится», как если бы он имел:

    WHERE t.active = 1

Если в таблице нет названного столбца active, запрос «переводится», как если бы он имел:

    WHERE dummy.active = 1         -- which is true 
ypercubeᵀᴹ
источник
3

Количество клиентов на UserID с общим итогом, используя только usersтаблицу:

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

Если таблица клиентов удалила записи, сделайте это:

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;

Для usersтаблиц, у которых нет activeстолбца:

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

или

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;

Вам нужно будет выполнить эти запросы для каждой базы данных и UNION ALLрезультатов.

Если вы хотите использовать базу данных INFORMATION_SCHEMA, то вот дикая догадка:

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;

Попробуйте!

RolandoMySQLDBA
источник
1

Я хотел бы дополнить ответ @ ypercubeᵀᴹ, но не могу писать комментарии из-за ограничений.

Если вы не знаете, какое имя столбца используется, и вам нужно получить его максимальное значение, вы можете сделать это:

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
источник