如果一列存在,如何选择特定行;如果一列不存在,如何选择所有行


23

我正在编写一个脚本,该脚本获取一些表的行数,但是对于某些表,我只想获取设置了标志(在本例中为active = 1)的行数。有没有一种方法可以在一个查询中做到这一点?

例如:

表中users有一个称为活动的列

clients没有称为活动的列

我想获得其中active = 1的用户数,而只是获得客户数。

在您说“只是硬编码”之前,这是一个查询,该查询正在python脚本内进行,该python脚本可以在许多不同的数据库上运行,并且我无法知道我的脚本将选择哪些表,以及它们是否具有名为的列active。我宁愿只有一个查询来完成所有操作,而不是两个单独的查询,并依靠mysql引发错误,所以我知道要使用另一个查询。


用户中有一个引用客户的clientid
Matt

Answers:


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

仅使用下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;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.