Cách chọn các hàng cụ thể nếu một cột tồn tại hoặc tất cả các hàng nếu một cột không


23

Tôi đang viết một tập lệnh nhận được số lượng hàng cho một vài bảng, tuy nhiên đối với một số bảng tôi chỉ muốn nhận một số lượng hàng được đặt cờ (trong trường hợp này là active = 1). Có cách nào tôi có thể làm điều này trong một truy vấn không?

Ví dụ:

Bảng userscó một cột được gọi là hoạt động

Bảng clientskhông có cột được gọi là hoạt động

Tôi muốn có được số lượng người dùng trong đó active = 1 và chỉ nhận được số lượng khách hàng.

Trước khi bạn nói "chỉ cần mã cứng", đây là một truy vấn nằm trong tập lệnh python có thể chạy trên nhiều cơ sở dữ liệu khác nhau và tôi không có cách nào biết được tập lệnh nào mà tập lệnh của tôi sẽ chọn và nếu chúng có một cột được gọi active, và Tôi muốn chỉ có một truy vấn để thực hiện tất cả thay vì hai truy vấn riêng biệt và dựa vào mysql để đưa ra một lỗi để tôi biết sử dụng một truy vấn khác.


có một khách hàng trong người dùng tham chiếu một khách hàng
Matt S.

Câu trả lời:


50

Suy nghĩ đầu tiên của tôi sẽ là sử dụng cái INFORMATION_SCHEMAđầu tiên, vì vậy bạn có thể biết (trong một truy vấn cho tất cả các bảng trong ví dụ MySQL) những bảng nào có một activecột và sau đó sử dụng thông tin đó để xây dựng các truy vấn của bạn. Và đây có lẽ là cách tiếp cận lành mạnh nhất.

Có một cách khác, khó khăn mặc dù nó hoạt động bất kể bảng có hay không một cột như vậy:

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

Đã thử nghiệm tại SQL-Fiddle Nó hoạt động như thế nào?

Nếu bảng có một cột được đặt tên active, truy vấn được "dịch" như thể nó có:

    WHERE t.active = 1

Nếu bảng không có cột được đặt tên active, truy vấn sẽ được "dịch" như thể nó có:

    WHERE dummy.active = 1         -- which is true 

3

Số lượng khách hàng trên mỗi ID người dùng với Grand Total chỉ sử dụng usersbảng:

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

Nếu bảng khách hàng đã xóa các bản ghi, thì hãy làm điều này:

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;

Đối với userscác bảng không có activecột:

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

hoặc là

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;

Bạn sẽ cần chạy các truy vấn này đối với từng cơ sở dữ liệu và UNION ALLkết quả.

Nếu bạn muốn khai thác cơ sở dữ liệu Information_SCHema thì đây là một phỏng đoán hoang dã:

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;

Hãy thử một lần !!!


1

Tôi muốn bổ sung câu trả lời của @ ypercubeᵀᴹ, nhưng tôi không thể viết bình luận vì những hạn chế.

Nếu bạn không biết tên cột nào được sử dụng và bạn cần lấy giá trị tối đa của nó, bạn có thể làm điều đó:

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;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.