在PHP中获取两次查询的总数


Getting the total for two queries in PHP

我正在按会话和每个会话特定的项目跟踪客户的成本。我试图获得总会话成本和会话项目成本(tbl_sessionitem的成本*计数)。但是当我检查结果时,代码输出错误:

警告:mysql_fetch_array():提供的参数不是一个有效的MySQL结果资源

这是我的表格:

CREATE TABLE tbl_session (
    `clientid` INT UNSIGNED NOT NULL,
    `sessioncost` DECIMAL(6,2) NOT NULL,
    `datetoday` DATETIME NOT NULL,
);
CREATE TABLE tbl_sessionitem (
    `clientid` INT UNSIGNED NOT NULL,
    `cost` DECIMAL(6,2) NOT NULL,
    `count` INT UNSIGNED NOT NULL,
    `datetoday` DATETIME NOT NULL
);
下面是我的php代码:
 <?php
 $date=$_POST['date'];
 mysql_connect("localhost","root","");
 mysql_select_db("database");
 $sql=mysql_query("
     SELECT id
          , SUM(tbl_session.sessioncost) AS 'totalcost'
          , SUM(tbl_sessionitem.count) * SUM(tbl_sessionitem.cost) AS 'totalquantitycost'
       FROM (
             SELECT clientid
                  , sessioncost
               FROM tbl_session
               WHERE datetoday = ('$date')
           UNION ALL
             SELECT clientid
                  , cost
              , count
               FROM tbl_sessionitem
             WHERE datetoday = ('$date')
         )
     GROUP BY id");

 while($row = mysql_fetch_array($sql))
 {
     echo $row['totalcost'];
     echo $row['totalquantitycost'];
 }
 mysql_close();
 ?>

警告的意思是:传递给mysql_fetch _array的值不是结果。mysql_query返回一个混合值;当查询失败时,它返回false。您需要执行错误检查。mysql_error会给你一个来自MySQL的错误信息,但是要小心不要输出数据库错误信息给非管理员。

如果你这样做了,你就会发现很多问题:

  • 子选择结果必须有别名。
  • 被联合的选择具有不同的列数
  • 子选择结果中没有名为"id"的列。
  • 聚合函数从子选择中引用表,但是外选择只能访问结果表(缺少别名的表)。

即使你修复了这些SQL错误,由于分组和聚合函数的工作方式,查询本身也不会给出你想要的结果。

有一个更好的方法。会话项与会话相关联,但在模式中,这种关联是松散的,通过datetoday列。因此,您会奇怪地使用联合。相反,应该为表创建代理键,并为会话项表提供一个引用会话表的列。同时,去掉多余的"tbl_"前缀。

CREATE TABLE sessions (
    id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
    client INT UNSIGNED NOT NULL,
    cost DECIMAL(5,2),
    `date` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    FOREIN KEY (client) REFERENCES clients (id)
) Engine=InnoDB;
CREATE TABLE session_items (
    id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
    session INT UNSIGNED NOT NULL,
    cost DECIMAL(5,2),
    `count` INT UNSIGNED,
    FOREIN KEY (session) REFERENCES sessions (id)
) Engine=InnoDB;

要获得给定一天的总会话成本和数量成本,您可以使用子查询来获得会话的数量成本(为了防止在总成本总和中多次包含会话成本,这是必要的),然后在外部查询中为每个客户端在给定一天的总成本求和会话和数量成本。

SELECT client, 
       SUM(cost) AS totalcost, 
       SUM(quantitycost) AS totalquantitycost
  FROM (
        SELECT client, 
               sessions.cost,
               SUM(session_items.`count`) * SUM(session_items.cost) AS quantitycost
          FROM sessions
            JOIN session_items ON sessions.id=session_items.session
          WHERE sessions.`date` = NOW()
          GROUP BY sessions.id
  ) AS session_invoices
  GROUP BY client
;

COUNT不能用作Column name,它是function,它是这样使用的:

Select COUNT(id) as countOfId FROM table

同时,我建议在PHP中完成所有这些计算,更容易维护和可能更好的性能,MySql不是一个计算器。

如果您想使用保留关键字作为列名,您需要添加反引号并且不要用大写字母书写,因为在这种情况下会降低可读性:

Select `count` from table

COST是什么?