Comment sélectionner des lignes spécifiques si une colonne existe ou toutes les lignes si une colonne n'existe pas


23

J'écris un script qui obtient un nombre de lignes pour quelques tables, mais pour certaines tables, je veux seulement obtenir un nombre de lignes où un indicateur est défini (dans ce cas, actif = 1). Existe-t-il un moyen de le faire dans une seule requête?

Par exemple:

La table usersa une colonne appelée active

La table clientsn'a pas de colonne appelée active

Je veux obtenir un nombre d'utilisateurs où active = 1 et simplement obtenir un nombre de clients.

Avant de dire "juste du code dur", c'est une requête qui va dans un script python qui pourrait être exécuté sur de nombreuses bases de données différentes et je n'ai aucun moyen de savoir quelles tables mon script va sélectionner et si elles ont une colonne appelée active, et Je préférerais avoir une seule requête pour tout faire au lieu de deux requêtes distinctes et compter sur mysql pour lancer une erreur, donc je sais utiliser l'autre.


il y a un client dans l'utilisateur qui référence un client
Matt S.

Réponses:


50

Ma première pensée serait d'utiliser la INFORMATION_SCHEMApremière, afin que vous sachiez (dans une requête pour toutes les tables de l'instance MySQL) quelles tables ont une activecolonne, puis utilisez ces informations pour construire vos requêtes. Et c'est probablement l'approche la plus sensée.

Il existe cependant une autre méthode délicate qui fonctionne, que la table ait ou non une telle colonne:

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

Testé chez SQL-Fiddle Comment ça marche?

Si la table a une colonne nommée active, la requête est "traduite" comme si elle avait:

    WHERE t.active = 1

Si la table n'a pas de colonne nommée active, la requête est "traduite" comme si elle avait:

    WHERE dummy.active = 1         -- which is true 

3

Nombre de clients par ID utilisateur avec Grand Total utilisant uniquement le userstableau:

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 table des clients a supprimé des enregistrements, procédez comme suit:

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;

Pour les userstables qui n'ont pas de activecolonne:

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

ou

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;

Vous devez exécuter ces requêtes sur chaque base de données et UNION ALLles résultats.

Si vous souhaitez exploiter la base de données INFORMATION_SCHEMA, voici une supposition sauvage:

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;

Essaie !!!


1

Je voudrais compléter la réponse du @ ypercubeᵀᴹ, mais je ne peux pas écrire de commentaires à cause des restrictions.

Si vous ne savez pas quel nom de colonne est utilisé et que vous devez obtenir sa valeur maximale, vous pouvez le faire:

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;
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.