MySQL UNION和PHP,不是朋友吗?

时间:2011-07-27 17:22:03

标签: php mysql join union

无论我做什么,我都无法将此代码发送到echo $done

以下是我的代码摘录,我无法为我的生活工作。我尝试了五种不同的方式,但没有任何工作。我唯一的结论是它因UNION而无效。

有解决方法吗?或者这甚至是问题?

$query01 = "SELECT COUNT(DISTINCT report) AS ip 
                FROM reports 
                    WHERE country =  '".$country."' 
                    AND YEAR(date) = '2011' 
                    AND MONTH(date) = '".$i."' AND 
                    status ='IP' 
        UNION
            SELECT COUNT(DISTINCT report) AS done 
                FROM reports 
                    WHERE country =  '".$country."' 
                    AND YEAR(date) = '2011' 
                    AND MONTH(date) = '".$i."' 
                    AND status ='DONE'";

$result01 = mysql_query($query01);

while ($row01 = mysql_fetch_array($result01)) {
    $ip = $row01['ip'];
    $done = $row01['done'];
    $all = $ip + $done;

    if($all>0){
        echo "<td>".$ip.":".$done."</td>";
    }

    else{
        echo "<td>-</td>";
    }

}

4 个答案:

答案 0 :(得分:2)

我猜您试图将ipdone作为每行的两列,在这种情况下, UNION 不是您拥有的查询的正确选择。

试试这个:

    $query01 = "SELECT a.ip, b.done 
  FROM 
    (
    SELECT COUNT(DISTINCT report) AS ip 
                    FROM reports 
                        WHERE country =  '".$country."' 
                        AND YEAR(date) = '2011' 
                        AND MONTH(date) = '".$i."' AND 
                        status ='IP' 
        ) a,
        (
                SELECT COUNT(DISTINCT report) AS done 
                    FROM reports 
                        WHERE country =  '".$country."' 
                        AND YEAR(date) = '2011' 
                        AND MONTH(date) = '".$i."' 
                        AND status ='DONE'
        ) b";

    $result01 = mysql_query($query01);

    while ($row01 = mysql_fetch_array($result01)) {
        $ip = $row01['ip'];
        $done = $row01['done'];
        $all = $ip + $done;

        if($all>0){
            echo "<td>".$ip.":".$done."</td>";
        }

        else{
            echo "<td>-</td>";
        }

    }

答案 1 :(得分:2)

你需要了解的关于UNION的事情:

  • UNION将行追加在一起,它不会将它们并排放置为列。
  • 列名由UNION中的第一个查询确定,不能更改。因此,您的列将命名为ip,并忽略您在第二个查询中定义的名称done

我建议对此查询使用GROUP BY而不是UNION。然后按行处理结果。这是一个例子(未经测试):

$query01 = "SELECT status, COUNT(DISTINCT report) AS c
            FROM reports 
            WHERE country = '{$country}' 
              AND date between '2011-{$i}-01' AND '2011-{$i}-32' 
              AND status IN ('IP','DONE')
            GROUP BY status";

$result01 = mysql_query($query01);

$status_count = array("IP"=>0, "DONE"=>0);
while ($row01 = mysql_fetch_array($result01)) {
    $status_count[ $row01["status"] ] = $row01["c"];
}

if (array_sum($status_count) > 0) {
    echo "<td>{$status_count["IP"]}:{$status_count["DONE"]}</td>";
}

else {
    echo "<td>-</td>";
}

答案 2 :(得分:1)

你的UNION正在联合两个具有不同列的查询:其中一个列有一个名为ip的列,另一个列有一个名为done的列。 MySQL可能会返回一个名为ip的结果集,因为这是它为此列遇到的第一个名称。 done列的值会连接到ip列的值,但该列的名称已为ip。没有名为done的列。也许试试:

$query01 = "SELECT COUNT(DISTINCT report) AS report_count, 'ip' as indicator 
                FROM reports 
                    WHERE country =  '".$country."' 
                    AND YEAR(date) = '2011' 
                    AND MONTH(date) = '".$i."' AND 
                    status ='IP' 
        UNION
            SELECT COUNT(DISTINCT report) AS report_count, 'done' as indicator 
                FROM reports 
                    WHERE country =  '".$country."' 
                    AND YEAR(date) = '2011' 
                    AND MONTH(date) = '".$i."' 
                    AND status ='DONE'";

现在两个查询都有相同的列,您可以选择打印indicator = 'done'所在的行。

答案 3 :(得分:1)

当您进行联合查询时,每个组件中的列数必须匹配(您的),并且发出的FIRST查询中的别名将是列名称将如何返回到客户端(您的脚本)。在您的情况下,您只会有一个ip列 - 永远不会有done列。

如果您需要区分结果中每一行的来源(发出哪个组件查询),您可以创建一个虚拟列来指示源:

SELECT 'ip' as src, COUNT(...) as cnt
UNION
SELECT 'done' as src, COUNT...) as cnt

所以现在您将返回两列,并可以$row['src']$row['cnt']访问它们。