วิธีการเลือกแถวเฉพาะถ้ามีคอลัมน์อยู่หรือทุกแถวถ้าไม่มีคอลัมน์


23

ฉันกำลังเขียนสคริปต์ที่ได้รับจำนวนแถวสำหรับตารางไม่กี่อย่างไรก็ตามสำหรับบางตารางฉันต้องการได้รับจำนวนแถวที่มีการตั้งค่าสถานะ (ในกรณีนี้ใช้งาน = 1) มีวิธีที่ฉันสามารถทำได้ในแบบสอบถามหรือไม่

เช่น:

ตารางusersมีคอลัมน์ที่เรียกว่าใช้งานอยู่

ตารางclientsไม่มีคอลัมน์ที่เรียกว่าใช้งานอยู่

ฉันต้องการรับจำนวนผู้ใช้ที่มีการใช้งาน = 1 และเพิ่งได้รับจำนวนลูกค้า

ก่อนที่คุณจะพูดว่า "แค่เขียนโค้ดยาก ๆ " นี่คือข้อความค้นหาที่อยู่ในสคริปต์ python ที่สามารถเรียกใช้บนฐานข้อมูลที่แตกต่างกันมากมายและฉันไม่มีทางรู้ว่าตารางสคริปต์ของฉันจะถูกเลือกและหากมีคอลัมน์ที่เรียกว่าactiveและ ฉันต้องการมีเพียงหนึ่งแบบสอบถามที่จะทำมันทั้งหมดแทนที่จะเป็นสองคนแยกต่างหากและอาศัย mysql เพื่อโยนข้อผิดพลาดดังนั้นฉันรู้ว่าจะใช้อีกคนหนึ่ง


มีรหัสลูกค้าในผู้ใช้ที่อ้างอิงถึงลูกค้า
Matt S.

คำตอบ:


50

ความคิดแรกของฉันคือการใช้สิ่งINFORMATION_SCHEMAแรกดังนั้นคุณจะได้รู้ (ในหนึ่งแบบสอบถามสำหรับตารางทั้งหมดในอินสแตนซ์ MySQL) ซึ่งตารางใดมีactiveคอลัมน์แล้วใช้ข้อมูลนั้นเพื่อสร้างแบบสอบถามของคุณ และนี่อาจเป็นวิธีที่มีสติมากที่สุด

มีอีกวิธีหนึ่งที่ยุ่งยากหากใช้งานได้ไม่ว่าตารางจะมีคอลัมน์หรือไม่:

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

ทดสอบที่SQL-Fiddleมันทำงานอย่างไร?

หากตารางมีชื่อคอลัมน์activeแบบสอบถามจะ "แปล" ราวกับว่ามันมี:

    WHERE t.active = 1

หากตารางไม่มีชื่อคอลัมน์activeแบบสอบถามจะ "แปล" ราวกับว่ามันมี:

    WHERE dummy.active = 1         -- which is true 

3

จำนวนลูกค้าต่อ UserID ที่มียอดรวมทั้งหมดโดยใช้usersตารางเท่านั้น:

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.