列が存在する場合は特定の行を、列が存在しない場合はすべての行を選択する方法


23

いくつかのテーブルの行数を取得するスクリプトを作成していますが、一部のテーブルでは、フラグが設定されている行数のみを取得したい(この場合はactive = 1)。1つのクエリでこれを行う方法はありますか?

例えば:

テーブルusersにactiveという列があります

テーブルにclientsactiveという列がありません

active = 1のユーザーの数を取得し、クライアントの数を取得したいだけです。

あなたが言う前に「だけでハードコードは、それが」これは、多くの異なるデータベース上で実行することができPythonスクリプト内で起こっているクエリであり、私は私のスクリプトを選択し、それらが列を持っている場合に呼び出されますどのようなテーブル知る方法はありませんactiveし、 2つの別々のクエリではなく、1つのクエリだけですべてを実行し、mysqlに依存してエラーをスローすることで、もう1つのクエリを使用することができます。


ユーザーでのClientIDを参照し、クライアントことがあります
マット・S.

回答:


50

私の最初の考えは最初のものを使用するINFORMATION_SCHEMAことですので、どのテーブルにactive列があるかを(MySQLインスタンスのすべてのテーブルに対する1つのクエリで)知り、その情報を使用してクエリを構築します。そして、これはおそらく最も健全なアプローチです。

テーブルにそのような列があるかどうかに関係なく機能しますが、もう1つのトリッキーな方法があります:

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

でテストSQL-フィドルどのように動作しますか?

テーブルにという名前の列がある場合、activeクエリは次のように「翻訳」されます。

    WHERE t.active = 1

テーブルにという名前の列がない場合、activeクエリは次のように「翻訳」されます。

    WHERE dummy.active = 1         -- which is true 

3

usersテーブルのみを使用した総計を持つユーザーIDごとのクライアント数:

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;

試してみる !!!


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;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.