2012-06-26 42 views
0

即使阅读所有相关的主题工作后,没有什么帮助:计数都不能正确使用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']; 

的错误,我得到:

注意:未定义指数:NUM中....在线..

我在做什么错?

+3

什么在$ Q3 :)做过的var_dump上呢? – Brian

+0

array(2){[0] => string(1)“1”[“count(*)”] => string(1)“1”} – Mark

+0

您的AS号是错误的。 –

回答

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%' 
+0

它死了:每个派生表都必须有自己的别名 – Mark

+0

@Mark ok然后给它一个不同的别名,只是不是num。我所做的一点是,你正在调用子查询'num',而不是计数结果。我将编辑更清晰 –

1

您的查询计数来自名为'num'的子查询的结果。

这意味着,没有结果中名为num,你可以不喜欢select count(*) as myNum 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"; 

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

+0

谢谢指出。 'selected'答案解决了语法问题,但似乎并没有解决SQL的一个更基本的问题。 – spencer7593

+0

而不是“count”可能想“总结”2个独立的结果? – Nanne

1

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

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

+0

谢谢,我将从此开始:) – Mark

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"; 
+0

谢谢!有用! “AS sub”的含义是什么? (因为它做出了改变) – Mark

+0

它并没有真正有所作为。第一行“select count(1)as num”的改变做到了。你甚至可以删除最后一个“AS sub” –

+0

实际上我不能,它死了:每个派生表都必须有自己的别名 – Mark

0

您的查询(一旦你别名最count(*) as num,将会返回1或2,根据您的两个子查询别名为“总”的表述是否相等或不

这是没有必要使用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 

这可能会比您的查询更高效地运行。

说了这么多,一点也不清楚,这是你真正追求的结果集。


附录:更正。该查询不完全等同。当剪辑表为空时(不包含行),此查询将返回不同的结果。这可能是固定的,但我不相信这实际上是马克之后的结果集。

来处理情况,剪辑表是空的条件:

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 
+0

我不熟悉这个语法(因为我在MySQL中的知识有限),所以我只是复制粘贴它,结果是:“每个派生表都必须有自己的别名”。代码是否被切断(最后一个字符是“c”)? – Mark

+0

这些SQL语句中的最后一个字符(“c”)是派生表所需的别名。它需要在那里。 – spencer7593