Come selezionare righe specifiche se esiste una colonna o tutte le righe se non esiste una colonna


23

Sto scrivendo uno script che ottiene un conteggio di righe per alcune tabelle, tuttavia per alcune tabelle voglio ottenere solo un conteggio delle righe in cui è impostato un flag (in questo caso attivo = 1). C'è un modo per farlo in una query?

Per esempio:

La tabella usersha una colonna chiamata attiva

La tabella clientsnon ha una colonna chiamata attiva

Voglio ottenere un conteggio di utenti dove active = 1 e ottenere solo un conteggio di client.

Prima di dire "basta codificarlo", questa è una query che si trova all'interno di uno script Python che potrebbe essere eseguito su numerosi database diversi e non ho modo di sapere quali tabelle verranno selezionate dal mio script e se hanno una colonna chiamata active, e Preferirei avere una sola query per fare tutto invece di due distinti e basarmi su mysql per lanciare un errore, quindi so di usare l'altro.


c'è un clientid nell'utente che fa riferimento a un client
Matt S.

Risposte:


50

Il mio primo pensiero sarebbe quello di utilizzare il INFORMATION_SCHEMAprimo, quindi puoi conoscere (in una query per tutte le tabelle nell'istanza di MySQL) quali tabelle hanno una activecolonna e quindi utilizzare tali informazioni per costruire le tue query. E questo è probabilmente l'approccio più sano.

C'è un altro modo complicato, tuttavia, che funziona indipendentemente dal fatto che la tabella abbia o meno una tale colonna:

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

Testato su SQL-Fiddle Come funziona?

Se la tabella ha una colonna denominata active, la query viene "tradotta" come se avesse:

    WHERE t.active = 1

Se la tabella non ha una colonna denominata active, la query viene "tradotta" come se avesse:

    WHERE dummy.active = 1         -- which is true 

3

Conteggio dei client per ID utente con totale complessivo utilizzando solo la userstabella:

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

Se la tabella dei client ha dei record eliminati, procedere come segue:

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;

Per le userstabelle che non hanno una activecolonna:

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;

Dovresti eseguire queste query su ciascun database e UNION ALLsui risultati.

Se vuoi sfruttare il database INFORMATION_SCHEMA, ecco un'ipotesi selvaggia:

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;

Provaci !!!


1

Vorrei integrare la risposta di @ ypercubeᵀᴹ, ma non riesco a scrivere commenti a causa delle restrizioni.

Se non sai quale nome di colonna viene utilizzato e devi ottenere il suo valore massimo, puoi farlo:

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;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.