计数与UNION无法正常工作

时间:2012-06-26 15:18:10

标签: php mysql count union

即使阅读了所有相关主题,也没有任何帮助:

$q="select count(*) from (
        SELECT COUNT(*) AS total
          FROM clips
         WHERE ((dimensions like('%concert%') AND dimensions NOT like('concert'))
            OR (file_format like('%concert%') AND file_format NOT like('concert')))
         UNION DISTINCT 
        SELECT COUNT(*) AS total
          FROM clips
         WHERE (dimensions like('concert') OR file_format like('concert'))
    ) AS num";
$q2 = mysql_query($q) or die(mysql_error());
$q3 = mysql_fetch_array($q2);
echo $q3['num'];

我得到的错误:

  

注意:未定义索引:在......中的数字......

我做错了什么?

5 个答案:

答案 0 :(得分:2)

您将num设置为表别名,而不是计数。试试这个

$q="select count(*) AS num from (
    SELECT COUNT(*) AS total
      FROM clips
     WHERE ((dimensions like('%concert%') AND dimensions NOT like('concert'))
        OR (file_format like('%concert%') AND file_format NOT like('concert')))
     UNION DISTINCT
    SELECT COUNT(*) AS total
      FROM clips
     WHERE (dimensions like('concert') OR file_format like('concert'))
) AS sub_query_alias_that_is_required_but_pointless";
$q2 = mysql_query($q) or die(mysql_error());
$q3 = mysql_fetch_array($q2);
echo $q3['num'];

但是,您可能正在寻找的更多预期功能是计算总行数,而不是计算您拥有的计数。此外,由于您只是查询clips表,我认为您根本不需要UNION。基于你在问题中的逻辑,我认为(但不能在没有实际数据的情况下测试它)它在逻辑上等同于这个非常简单的查询,除非我严重缺少某些东西。此查询可能更友好,更清晰。

SELECT COUNT(1) AS num
FROM clips
WHERE dimensions like '%concert%' 
   OR file_format like '%concert%'

答案 1 :(得分:1)

您的查询会计算名为'num'的子查询的结果。

这意味着没有名为num的结果,你可以为{<1>}做一些事情

现在你在想的是:

select count(*) as myNum from...

这会给你一个计数,而不是结果。所以你在计算数量,而不是将它们加在一起。

答案 2 :(得分:1)

重新格式化查询后,您会看到最后一个“as num”被引用到整个select,而不是count(*),我想这就是你想要的别名。

尝试始终为每个条目在单独的行中格式化查询,这极大地帮助您进行调试。

答案 3 :(得分:1)

我编辑了您的问题以更好地布置查询。问题是您要将别名分配给子选择而不是结果值。另外,当你计算行数时,出于性能原因,做count(1)然后count(*)要好得多,因为count(1) simply uses the constant in counting, while count(*)`必须检索实际递增计数之前的行。试试这个:

$q="select count(1) as num from (
        SELECT COUNT(1) AS total
          FROM clips
         WHERE ((dimensions like('%concert%') AND dimensions NOT like('concert'))
            OR (file_format like('%concert%') AND file_format NOT like('concert')))
         UNION DISTINCT
        SELECT COUNT(1) AS total
          FROM clips
         WHERE (dimensions like('concert') OR file_format like('concert'))
    ) AS sub";

答案 4 :(得分:0)

您的查询(一旦您对最外面的count(*) as num进行别名,将返回1或2,具体取决于两个子查询中的别名为“total”的表达式是否相等。

没有必要使用UNION并扫描clips表两次以返回此结果。 单次扫描就足够了。此查询将返回一个等效结果,只需通过剪辑表进行一次扫描:

SELECT CASE WHEN c.total_1 = c.total_2 THEN 1 ELSE 2 END AS num
  FROM
(
SELECT SUM(CASE WHEN ((dimensions like('%concert%') AND dimensions NOT like('concert'))
                  OR (file_format like('%concert%') AND file_format NOT like('concert')))
                THEN 1 ELSE 0 END
          ) AS total_1
     , SUM(CASE WHEN (dimensions like('concert') OR file_format like('concert'))
                THEN 1 ELSE 0 END
          ) AS total_2
  FROM clips
) c

这可能比您的查询更有效率。

尽管如此,我们并不清楚这是你真正追求的结果集。


ADDENDUM:更正。此查询并不完全等效。当剪辑表为空(不包含任何行)时,此查询将返回不同的结果。这可能是固定的,但我不相信这实际上是Mark所追求的结果集。

要处理剪辑表为空的情况:

SELECT CASE WHEN IFNULL(c.total_1,0) = IFNULL(c.total_2,0) THEN 1 ELSE 2 END AS num
  FROM (SELECT 1) i LEFT JOIN
(
SELECT SUM(CASE WHEN ((dimensions like('%concert%') AND dimensions NOT like('concert'))
                  OR (file_format like('%concert%') AND file_format NOT like('concert')))
                THEN 1 ELSE 0 END
          ) AS total_1
     , SUM(CASE WHEN (dimensions like('concert') OR file_format like('concert'))
                THEN 1 ELSE 0 END
          ) AS total_2
  FROM clips
) c