Cara memilih baris tertentu jika ada kolom atau semua baris jika kolom tidak

23

Saya sedang menulis skrip yang mendapat hitungan baris untuk beberapa tabel, namun untuk beberapa tabel saya hanya ingin mendapatkan hitungan baris di mana sebuah flag ditetapkan (dalam hal ini aktif = 1). Apakah ada cara saya bisa melakukan ini dalam satu permintaan?

Misalnya:

Tabel usersmemiliki kolom yang disebut aktif

Tabel clientstidak memiliki kolom yang disebut aktif

Saya ingin mendapatkan jumlah pengguna yang aktif = 1 dan hanya mendapatkan jumlah klien.

Sebelum Anda mengatakan "hanya kode keras", ini adalah kueri yang masuk ke dalam skrip python yang dapat dijalankan pada berbagai basis data dan saya tidak memiliki cara untuk mengetahui tabel apa yang akan dipilih skrip saya dan jika ada kolom yang dipanggil active, dan Saya lebih suka memiliki hanya satu query untuk melakukan semuanya daripada dua yang terpisah dan mengandalkan mysql untuk melempar kesalahan jadi saya tahu menggunakan yang lain.

Matt S.
sumber
ada clientid di pengguna yang mereferensikan klien
Matt S.

Jawaban:

50

Pikiran pertama saya adalah menggunakan yang INFORMATION_SCHEMApertama, sehingga Anda mengenal (dalam satu permintaan untuk semua tabel dalam contoh MySQL) tabel mana yang memiliki activekolom dan kemudian menggunakan info itu untuk membangun kueri Anda. Dan ini mungkin pendekatan yang paling waras.

Ada satu cara lain yang rumit yang berfungsi tidak masalah apakah tabelnya memiliki atau tidak kolom seperti itu:

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

Diuji di SQL-Fiddle Bagaimana cara kerjanya?

Jika tabel memiliki kolom bernama active, kueri "diterjemahkan" seolah-olah memiliki:

    WHERE t.active = 1

Jika tabel tidak memiliki nama kolom active, kueri "diterjemahkan" seolah-olah memiliki:

    WHERE dummy.active = 1         -- which is true 
ypercubeᵀᴹ
sumber
3

Hitungan Klien Per UserID dengan Grand Total hanya menggunakan userstabel:

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

Jika tabel klien memiliki catatan yang dihapus, maka lakukan ini:

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;

Untuk userstabel yang tidak memiliki activekolom:

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

atau

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;

Anda harus menjalankan kueri ini terhadap setiap basis data dan UNION ALLhasilnya.

Jika Anda ingin memanfaatkan basis data INFORMATION_SCHEMA maka ini adalah tebakan liar:

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;

Cobalah !!!

RolandoMySQLDBA
sumber
1

Saya ingin menambahkan jawaban dari @ ypercubeᵀᴹ, tetapi saya tidak dapat menulis komentar karena batasannya.

Jika Anda tidak tahu nama kolom apa yang digunakan, dan Anda perlu mendapatkan nilai maksimalnya, Anda bisa melakukannya:

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
sumber