So wählen Sie bestimmte Zeilen aus, wenn eine Spalte vorhanden ist, oder alle Zeilen, wenn eine Spalte nicht vorhanden ist


23

Ich schreibe ein Skript, das die Anzahl der Zeilen für einige Tabellen ermittelt. Bei einigen Tabellen möchte ich jedoch nur die Anzahl der Zeilen ermitteln, bei denen ein Flag gesetzt ist (in diesem Fall active = 1). Gibt es eine Möglichkeit, dies in einer Abfrage zu tun?

Z.B:

Tabelle usershat eine Spalte mit dem Namen aktiv

In der Tabelle clientsist keine Spalte mit dem Namen active vorhanden

Ich möchte die Anzahl der Benutzer ermitteln, bei denen active = 1 ist, und möchte nur die Anzahl der Clients ermitteln.

Bevor Sie "nur harten Code" sagen, ist dies eine Abfrage, die in einem Python-Skript ausgeführt wird, das auf zahlreichen verschiedenen Datenbanken ausgeführt werden kann, und ich habe keine Möglichkeit zu wissen, welche Tabellen mein Skript auswählt und ob sie eine Spalte mit dem Namen " activeund" haben Ich würde es vorziehen, nur eine Abfrage zu haben, um alles zu erledigen, anstatt zwei separate und mich auf mysql zu verlassen, um einen Fehler zu werfen, damit ich weiß, dass ich die andere verwenden kann.


Der Benutzer hat eine Client-ID, die auf einen Client verweist
Matt S.,

Antworten:


50

Mein erster Gedanke wäre, den INFORMATION_SCHEMAersten zu verwenden, damit Sie wissen (in einer Abfrage für alle Tabellen in der MySQL-Instanz), welche Tabellen eine activeSpalte haben, und diese Informationen dann verwenden, um Ihre Abfragen zu erstellen. Und dies ist wahrscheinlich der vernünftigste Ansatz.

Es gibt einen anderen, kniffligen Weg, der funktioniert, egal ob die Tabelle eine solche Spalte hat oder nicht:

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

Getestet bei SQL-Fiddle Wie funktioniert es?

Wenn die Tabelle eine Spalte mit dem Namen hat active, wird die Abfrage wie folgt "übersetzt":

    WHERE t.active = 1

Wenn die Tabelle keine Spalte mit dem Namen hat active, wird die Abfrage so "übersetzt", als ob sie Folgendes hätte:

    WHERE dummy.active = 1         -- which is true 

3

Anzahl der Clients pro Benutzer-ID mit Gesamtsumme unter Verwendung nur der usersTabelle:

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

Wenn die clients-Tabelle Datensätze gelöscht hat, gehen Sie folgendermaßen vor:

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;

Für usersTabellen ohne activeSpalte:

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

oder

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;

Sie müssten diese Abfragen für jede Datenbank und UNION ALLdie Ergebnisse ausführen .

Wenn Sie die Datenbank INFORMATION_SCHEMA nutzen möchten, können Sie Folgendes raten:

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;

Versuche es !!!


1

Ich möchte die Antwort des @ ypercubeᵀᴹ ergänzen, kann aber wegen der Einschränkungen keine Kommentare schreiben.

Wenn Sie nicht wissen, welcher Spaltenname verwendet wird, und Sie dessen Maximalwert ermitteln müssen, können Sie Folgendes tun:

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;
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.