Jak wybrać określone wiersze, jeśli kolumna istnieje, lub wszystkie wiersze, jeśli kolumna nie istnieje

23

Piszę skrypt, który pobiera liczbę wierszy dla kilku tabel, jednak dla niektórych tabel chcę uzyskać tylko liczbę wierszy, w których ustawiona jest flaga (w tym przypadku aktywna = 1). Czy mogę to zrobić w jednym zapytaniu?

Na przykład:

Tabela usersma kolumnę o nazwie aktywna

Tabela clientsnie ma kolumny o nazwie aktywnej

Chcę uzyskać liczbę użytkowników, których aktywność = 1, i po prostu uzyskać liczbę klientów.

Zanim powiesz „po prostu twardy kod”, jest to zapytanie wchodzące w skład skryptu Pythona, które można uruchomić w wielu różnych bazach danych, a ja nie mam pojęcia, jakie tabele wybierze mój skrypt i czy mają kolumnę o nazwie active, i Wolę mieć tylko jedno zapytanie, aby zrobić to wszystko zamiast dwóch osobnych i polegać na mysql, aby zgłosić błąd, więc wiem, że mogę użyć drugiego.

Matt S.
źródło
w kliencie znajduje się klient, który odwołuje się do klienta
Matt S.

Odpowiedzi:

50

Moją pierwszą myślą byłoby użycie INFORMATION_SCHEMApierwszej, abyś wiedział (w jednym zapytaniu dla wszystkich tabel w instancji MySQL), które tabele mają activekolumnę, a następnie wykorzystał te informacje do zbudowania twoich zapytań. I to jest chyba najbardziej rozsądne podejście.

Jest jeszcze jeden, trudny sposób, który działa niezależnie od tego, czy tabela ma taką kolumnę, czy nie:

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

Testowane w SQL-Fiddle Jak to działa?

Jeśli tabela ma nazwę kolumny active, zapytanie jest „tłumaczone” tak, jakby miało:

    WHERE t.active = 1

Jeśli tabela nie ma nazwanej kolumny active, zapytanie jest „tłumaczone” tak, jakby miało:

    WHERE dummy.active = 1         -- which is true 
ypercubeᵀᴹ
źródło
3

Liczba klientów na identyfikator użytkownika z sumą całkowitą przy użyciu tylko userstabeli:

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

Jeśli tabela klientów usunęła rekordy, wykonaj następujące czynności:

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;

W przypadku userstabel, które nie mają activekolumny:

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

lub

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;

Musisz uruchomić te zapytania dla każdej bazy danych i UNION ALLwyników.

Jeśli chcesz wykorzystać bazę danych INFORMACJE_SCHEMA, oto zgadywanie:

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;

Spróbuj !!!

RolandoMySQLDBA
źródło
1

Chciałbym uzupełnić odpowiedź na @ ypercubeᵀᴹ, ale nie mogę pisać komentarzy z powodu ograniczeń.

Jeśli nie wiesz, jaka nazwa kolumny jest używana i musisz uzyskać jej maksymalną wartość, możesz to zrobić:

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
źródło