Reputation: 21
I'm tracking costs to clients by session and by items specific to each session. I'm trying to get the total session costs and session item costs (cost * count from tbl_sessionitem
). But when I check the results, the code outputs the error:
Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource
Here are my tables:
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
);
Here is my php code:
<?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();
?>
Upvotes: 1
Views: 169
Reputation: 77400
The warning means what it said: the value passed to mysql_fetch _array
isn't a result. mysql_query
returns a mixed value; when the query fails, it returns false
. You need to perform error checking. mysql_error
will give you an error message from MySQL, though be careful never to output database error messages to non-admins.
If you had done that, you would have seen a number of problems:
Even if you fix those SQL errors, the query itself won't give the results you're looking for, due to the way grouping and aggregate functions work.
There's a much better approach. Session items are associated with sessions, but in the schema this association is loose, via the datetoday
column. As a result, you have the odd use of unions. Instead, create surrogate keys for the tables and give the session items table a column that refers to the session table. While you're at it, drop the redundant "tbl_" prefix.
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;
To get the total session cost and quantity cost for a given day, you can use a subquery to get the quantity cost for a session (necessary to prevent including session costs multiple time in the totalcost sum), then sum the session and quantity costs in an outer query for each client's total costs for a given day.
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
;
Upvotes: 2
Reputation: 3460
COUNT
is not to be used as a Column name
, it's a function
, it's used like this:
Select COUNT(id) as countOfId FROM table
Also, I would recommend doing all those calculations in PHP
, much easier to maintain and probably better performance, MySql isn't meant as a calculator.
If you want to use reserved keywords as column names, you need to add backticks and don't write them in capitals because that decreases readability in this case:
Select `count` from table
And what is COST
?
Upvotes: 0