having difficulties with a form and mysql. 3 tables, 1 sum of a tables values. The form provides the value to search, but it does not work with the "WHERE >= '$search_total_rating" being in the wrong place, i am doing something very wrong here.
$result = mysql_query("SELECT coffeeshops.*, services.*, ratings.*, sum(temp.total) as final_total FROM coffeeshops inner join services on coffeeshops.shop_id=services.shop_id
inner join ratings on coffeeshops.shop_id=ratings.shop_id
inner join (select SUM(comfort + service + ambience + friendliness + spacious)/(5) / COUNT(shop_id) AS total, shop_id FROM ratings GROUP BY shop_id) as temp on coffeeshops.shop_id=temp.shop_id WHERE >= '$search_total_rating'");
I do not fully understand this, but what i am trying to do is WHERE the total rating sum is >= selected rating. I am trying to access final_total which is not an actual column in my database, that is why SUM is being used to get the total rating for each shop. Hopefully it is a minor shuffle of the code. Thanks
You should use having instead of where
SELECT coffeeshops.*, services.*, ratings.*, sum(temp.total) as final_total
FROM coffeeshops inner join services on coffeeshops.shop_id=services.shop_id
inner join ratings on coffeeshops.shop_id=ratings.shop_id
inner join (
select SUM(comfort + service + ambience + friendliness + spacious)/5/ COUNT(shop_id) AS total, shop_id
FROM ratings GROUP BY shop_id)
as temp on coffeeshops.shop_id=temp.shop_id
having final_total >= '$search_total_rating'
You have already calculated your total in the subquery. No need for a second SUM().
SELECT coffeeshops.*
, services.*
, ratings.*
, temp.total as final_total
FROM coffeeshops
inner join services
on coffeeshops.shop_id = services.shop_id
inner join ratings
on coffeeshops.shop_id = ratings.shop_id
inner join
( select SUM(comfort + service + ambience + friendliness + spacious) / 5
/ COUNT(shop_id) AS total
, shop_id
FROM ratings
GROUP BY shop_id
) as temp
on coffeeshops.shop_id = temp.shop_id
WHERE temp.total >= '$search_total_rating'
You could also use a HAVING in the subquery:
SELECT coffeeshops.*
, services.*
, ratings.*
, temp.total as final_total
FROM coffeeshops
inner join services
on coffeeshops.shop_id = services.shop_id
inner join ratings
on coffeeshops.shop_id = ratings.shop_id
inner join
( select SUM(comfort + service + ambience + friendliness + spacious) / 5
/ COUNT(shop_id) AS total
, shop_id
FROM ratings
GROUP BY shop_id
HAVINGE total >= '$search_total_rating'
) as temp
on coffeeshops.shop_id = temp.shop_id
Related
I have a SALES RECEIPT table and a RETURNS table. The information in the two tables are independent of each other except that each table has the Rep_ID attribute from the SALES_REP table.
In the first sub-query, I calculate the sum of the “Total Sales” and the “Gross Commission” from the SALES RECEIPT table for each sales person on a monthly basis.
In the second sub-query, I calculate the sum of the “Return Sales” and the “Lost Commission” from the RETURNS table for each sales person on a monthly basis.
In the main query, I want to display for each sales person on a monthly basis the “Total Sales”,
“Gross Commission”, “Return Sales”, “Lost Commission” and “Net Commission”. The “Net Commission” is the “Gross Commission” minus the “Lost Commission”.
With the code I have, I get the error message:
"The Microsoft Access database engine cannot find the input table or query ‘totSales’. Make sure it exists and that its name is spelled correctly.”
Select
totSales.Year-Month as [Month/Year],
SALES_REP.rep_name as [Sales Person],
SUM(totSales.[Total Sales]) as [Total Sales],
SUM(totSales.[Gross Commission]) as [Gross Commission],
SUM(totReturns.[Return Sales],0) as [Sales Returns],
SUM(totReturns.[Lost Commission],0) as [Lost Commission],
Round([Gross Commission] - [Lost Commission],2) AS [Net Commission],
(SELECT
Format(SALES_RECEIPT.sale_date,'yyyy-mm') AS [Year-Month],
SALES_RECEIPT.rep_id,
( SALES_RECEIPT.selling_price * SALES_RECEIPT.quantity) AS [Total Sales],
((Nz(SALES_RECEIPT.selling_price, 0) * Nz( SALES_RECEIPT.quantity, 0)) * (Nz(SALES_RECEIPT.commission_percent, 100) * 0.001)) AS [Gross Commission]
FROM
SALES_RECEIPT
WHERE
SALES_RECEIPT.sale_date Between #1/1/2000# And #12/31/2050#) AS totSales,
(SELECT
RETURNS.rep_id,
(Nz(RETURNS.selling_price * RETURNS.quantity)) AS [Sales Returns],
((Nz(RETURNS.selling_price, 0) * Nz(RETURNS.quantity, 0)) * (Nz(RETURNS.commission_percent, 100) * 0.001)) AS [Lost Commission]
FROM
RETURNS
WHERE
RETURNS.return_date Between #1/1/2000# And #12/31/2050#) As totReturns
From (totSales
LEFT JOIN totReturns on totReturns.rep_id = totSales.rep_id)
INNER JOIN SALES_REP ON totSales.REP_ID = SALES_REP.rep_id
Group By totSales.Year-Month, totSales.rep_name;
The query below returns monthly sales commission data but only for one sales person. I want the above query to return the exact same results as the query below but for all sales persons not just one sales person.
SELECT Format(DatePart("m",months.month_start),"00") & "/" & Year(months.month_start) AS [Month/Year],
(SELECT SALES_REP.rep_name FROM SALES_REP WHERE SALES_REP.rep_id = 1) AS [Sales Person],
(select Round(Nz(Sum(sales_receipt.SELLING_PRICE * sales_receipt.quantity),0) ,2)
FROM SALES_RECEIPT INNER JOIN SALES_REP ON SALES_REP.REP_ID = SALES_RECEIPT.REP_ID
WHERE SALES_RECEIPT.[SALE_DATE] between months.month_start and months.month_end and SALES_REP.rep_id = 1) AS [Total Sales],
(SELECT Round((Sum(((Nz(SALES_RECEIPT.SELLING_PRICE,0)*Nz(sales_receipt.quantity,0))*(Nz(sales_receipt.commission_percent,100)*0.001)))),2)
FROM SALES_RECEIPT INNER JOIN SALES_REP ON SALES_REP.REP_ID = SALES_RECEIPT.REP_ID
WHERE SALES_RECEIPT.[SALE_DATE] between months.month_start and months.month_end and SALES_REP.rep_id = 1) AS [Gross Commission],
(SELECT Round(Nz(Sum(returns.selling_price * returns.quantity), 0),2)
FROM (returns inner JOIN inventory ON INVENTORY.INVENTORY_ID = returns.INVENTORY_ID)
LEFT JOIN SALES_REP ON SALES_REP.REP_ID = returns.REP_ID
WHERE returns.return_date between months.month_start and months.month_end AND SALES_REP.rep_id = 1) AS [Sales Returns],
(SELECT Round(Nz((Sum(((Nz(returns.SELLING_PRICE,0)*Nz(returns.quantity,0))*(Nz(returns.commission_percent,100)*0.001)))),0),2)
FROM (returns inner JOIN inventory ON INVENTORY.INVENTORY_ID = returns.INVENTORY_ID)
LEFT JOIN SALES_REP ON SALES_REP.REP_ID = returns.REP_ID
WHERE returns.return_date between months.month_start and months.month_end AND SALES_REP.rep_id = 1) AS [Lost Commission],
(SELECT Round((Sum(((Nz(SALES_RECEIPT.SELLING_PRICE,0)*Nz(sales_receipt.quantity,0))*(Nz(sales_receipt.commission_percent,100)*0.001)))),2)
FROM SALES_RECEIPT INNER JOIN SALES_REP ON SALES_REP.REP_ID = SALES_RECEIPT.REP_ID WHERE SALES_RECEIPT.[SALE_DATE] between months.month_start and months.month_end and SALES_REP.rep_id = 1) - (SELECT Round(Nz((Sum(((Nz(returns.SELLING_PRICE,0)*Nz(returns.quantity,0))*(Nz(returns.commission_percent,100)*0.001)))),0),2)
FROM(returns inner JOIN inventory ON INVENTORY.INVENTORY_ID = returns.INVENTORY_ID)
LEFT JOIN SALES_REP ON SALES_REP.REP_ID = returns.REP_ID
WHERE returns.return_date between months.month_start and months.month_end AND SALES_REP.rep_id = 1) AS [Net Commission]
FROM
(SELECT DateSerial(Year(sale_date), Month(sale_date), 1) AS month_start,
DateAdd("d", -1, DateSerial(Year(sale_date), Month(sale_date) + 1, 1)) AS month_end
FROM SALES_RECEIPT
WHERE sale_date between #1/1/2000# And #12/31/2100#
GROUP BY Year(sale_date), Month(sale_date)) AS months;
Move the two subqueries so that they are in the FROM...JOIN section of the query. As #Leviathan noted, the query is currently treating them as if they were fields (which they aren't, of course).
Also: be sure that you include all of the fields by which you are grouping in the GROUP BY clause (and do not alias them--you'll get an error).
Here's a stab at the first query. Access is screwy with how it likes parentheses when you're doing multiple joins, so apologies if it doesn't work the first time:
Select
totSales.Year-Month as [Month/Year],
SALES_REP.rep_name as [Sales Person],
SUM(totSales.[Total Sales]) as [Total Sales],
SUM(totSales.[Gross Commission]) as [Gross Commission],
SUM(totReturns.[Return Sales],0) as [Sales Returns],
SUM(totReturns.[Lost Commission],0) as [Lost Commission],
Round(TotCommissions - TotLostCommissions,2) AS [Net Commission]
FROM
SALES_REP
INNER JOIN
(
(SELECT
Format(SALES_RECEIPT.sale_date,'yyyy-mm') AS [Year-Month],
SALES_RECEIPT.rep_id,
( SALES_RECEIPT.selling_price * SALES_RECEIPT.quantity) AS [Total Sales],
((Nz(SALES_RECEIPT.selling_price, 0) * Nz( SALES_RECEIPT.quantity, 0)) * (Nz(SALES_RECEIPT.commission_percent, 100) * 0.001)) AS [Gross Commission]
FROM
SALES_RECEIPT
WHERE
SALES_RECEIPT.sale_date Between #1/1/2000# And #12/31/2050#) AS totSales
LEFT JOIN
(SELECT
RETURNS.rep_id,
(Nz(RETURNS.selling_price * RETURNS.quantity)) AS [Returns Sales],
((Nz(RETURNS.selling_price, 0) * Nz(RETURNS.quantity, 0)) * (Nz(RETURNS.commission_percent, 100) * 0.001)) AS [Lost Commission]
FROM
RETURNS
WHERE
RETURNS.return_date Between #1/1/2000# And #12/31/2050#) As totReturns
on totReturns.rep_id = totSales.rep_id
)
ON totSales.REP_ID = SALES_REP.rep_id
Group By
totSales.Year-Month
,SALES_REP.rep_name
,Round(TotCommissions - TotLostCommissions,2)
;
Also: as a style thing: it's generally preferred to put the commas separating multiple fields on the line with the field that follows them, e.g.:
SELECT
SomeField
,SomeOtherField
not:
SELECT
SomeField,
SomeOtherField
Some folks get really bent out of shape about it, so probably a good idea to try and get in the habit of leading with the comma to spare yourself unnecessary criticism.
I am a newbie in mysql and php and not so experienced yet in making complicated queries.
Thanks of some users on stackoverflow below query is now successfully working.
the last bit I am missing now is to include calculating the difference between total from q1 and costs from q2 in this query. Thanks for your help in advance. cheers
Select * from ( SELECT invoice.eventid, invoice.invoiceno, event.clientid, client.clientid, clientname,
gross_amount, vat, total, due
FROM client, invoice, event
WHERE event.eventid = invoice.eventid
AND event.clientid = client.clientid)
as q1
inner JOIN (SELECT event_ma.eventid,
salary.staffid, Sum(cost_hour * Time_to_sec(Timediff(hours, pause))) / 3600 AS costs
FROM salary
JOIN event_ma ON salary.staffid = event_ma.staffid GROUP BY event_ma.eventid)
as q2
ON q1.eventid = q2.eventid
GROUP BY q1.eventid
Add the calculated field in your primary SELECT-statement:
Select *, (q1.total - q2.costs) AS difference
from ( SELECT invoice.eventid, invoice.invoiceno, event.clientid, client.clientid, clientname,
gross_amount, vat, total, due
FROM client, invoice, event
WHERE event.eventid = invoice.eventid
AND event.clientid = client.clientid)
as q1
inner JOIN (SELECT event_ma.eventid,
salary.staffid, Sum(cost_hour * Time_to_sec(Timediff(hours, pause))) / 3600 AS costs
FROM salary
JOIN event_ma ON salary.staffid = event_ma.staffid GROUP BY event_ma.eventid)
as q2
ON q1.eventid = q2.eventid
GROUP BY q1.eventid
I want to join two select queries and don't know how to do it.
The first query gives me information on the invoice number, the client, the eventid and the amount that are all saved in the invoice table :
SELECT invoice.Eventid, invoice.Invoiceno,
event.clientid, client.clientid, clientname, gross_amount, VAT, total, due
FROM client, invoice, event,
WHERE event.eventid=invoice.eventid and event.clientid = client.clientid group by invoice.eventid
The second query is checking the salary of the staffmember
SELECT event_ma.eventid, salary.staffid, SUM( cost_hour * TIME_TO_SEC( TIMEDIFF( hours, pause ) ) ) /3600 AS costs
FROM salary
JOIN event_ma ON salary.staffid = event_ma.staffid
GROUP BY event_ma.eventid
At the end I want to see the all relevant costs and income per event.
The way I understand the question, you can take the first query, and then join the second query where the eventID matches. Also, just pointing out that you're using old join syntax in the first query - rather than using:
Select table1.col, table2.col From
table1, table2
...
You should use:
Select table1.col, table2.col From
table1
INNER JOIN table2 On
table1.colID = table2.colID
...
And to answer your question:
SELECT invoice.eventid,
invoice.invoiceno,
event.clientid,
client.clientid,
clientname,
gross_amount,
vat,
total,
due
FROM client,
invoice,
event,
inner
JOIN (SELECT event_ma.eventid,
salary.staffid,
Sum(cost_hour * Time_to_sec(Timediff(hours, pause))) / 3600
AS
costs
FROM salary
JOIN event_ma
ON salary.staffid = event_ma.staffid
GROUP BY event_ma.eventid) x
ON invoice.eventid = x.eventid
WHERE event.eventid = invoice.eventid
AND event.clientid = client.clientid
GROUP BY invoice.eventid
You can actually use this way:
CREATE VIEW `inv` AS
SELECT invoice.Eventid AS inve, invoice.Invoiceno,
event.clientid, client.clientid, clientname, gross_amount, VAT, total, due
FROM client, invoice, event,
WHERE event.eventid=invoice.eventid and event.clientid = client.clientid group by invoice.eventid
CREATE VIEW `ev` AS
SELECT event_ma.eventid AS evee, salary.staffid, SUM( cost_hour * TIME_TO_SEC( TIMEDIFF( hours, pause ) ) ) /3600 AS costs
FROM salary
JOIN event_ma ON salary.staffid = event_ma.staffid
GROUP BY event_ma.eventid
And your final query as:
SELECT * FROM `inv`, `ev`
WHERE `inve` = `evee`;
Or you can also consider using MySQL JOIN this way:
SELECT * FROM `inv`
JOIN `ev` ON `inv`.`inve` = `ev`.`evee`;
You can write a query that takes subqueries as data sources:
select ...
from
(select ...) as q1
inner join (select ...) as q2 on ...
...
I have the following table structure:
Customers - Cust_Orders - Cust_Items - Cust_Payments - Drivers
id id id id id
company cid oid oid name
driver price amount
date qty date
vat
What I want to do is showing last unpaid order marked by a specific driver id + the sum of all unpaid orders for that particular customer except the order that is already selected.
Since there might be more than one cust_items & more than one cust_payments I had to use select from select as otherwise I would have wrong sums & things got messy till I reached a point I forgot what I was doing.
Any Help would be greatly appreciated.
My current SQL which lacks the final part only (sum of other unpaid orders amounts):
SELECT `customers`.`company`,
T1.*,
ROUND( IFNULL( SUM(`cust_payments`.`amount`), 0 ), 2) AS `paid`
FROM (
SELECT `cust_orders`.*,
ROUND( IFNULL( SUM(`cust_items`.`qty` * `cust_items`.`price`), 0 ), 2) AS `total`,
SUM( ( `cust_items`.`price` * `cust_items`.`qty` * `vat` ) / 100) AS `vat`
FROM `cust_orders`
LEFT JOIN `cust_items` ON `cust_orders`.`id` = `cust_items`.`oid`
GROUP BY `cust_orders`.`id`
) `T1`
LEFT JOIN `customers` ON `T1`.`cid` = `customers`.`id`
LEFT JOIN `cust_payments` ON `T1`.`id` = `cust_payments`.`oid`
WHERE `T1`.`driver` = ? GROUP BY `T1`.`id` HAVING (`T1`.`total` - `paid`) > ?
ORDER BY `T1`.`id` DESC LIMIT 1
Can you try
SELECT
x.id,
x.company,
y.id,
y.cid,
y.driver,
y.date,
#ut:=ROUND(SUM(z.qty*z.price),2) AS unpaid_total,
#uv:=SUM((#ut*z.vat)/100) AS unpaid_vat,
#st:=ROUND(SUM(b.qty*b.price),2)-#ut AS sum_total,
SUM((#st*b.vat)/100)-#uv AS sum_vat
FROM Customers x
INNER JOIN Cust_Orders y ON x.id=y.cid
INNER JOIN Cust_Items z ON y.id=z.oid
LEFT JOIN Cust_Orders a ON x.id=a.cid
LEFT JOIN Cust_Items b ON a.id=b.oid
WHERE
y.driver=? AND
NOT EXISTS (SELECT * FROM Cust_Payments WHERE oid=y.id) AND
NOT EXISTS (SELECT * FROM Cust_Payments WHERE oid=a.id)
GROUP BY x.id,x.company, y.id, y.cid, y.driver, y.date
I have a problem im my sql query:
SELECT table_2.id, SUM(table_2.time + table_4.time + table_6.time + table_8.time + table_10.time + table_12.time) AS total_time, SUM(table_2.connects + table_4.connects + table_6.connects + table_8.connects + table_10.connects + table_12.connects) AS total_connects FROM table_2
INNER JOIN table_4 ON table_2.id = table_4.id
INNER JOIN table_6 ON table_2.id = table_6.id
INNER JOIN table_8 ON table_2.id = table_8.id
INNER JOIN table_10 ON table_2.id = table_10.id
INNER JOIN table_12 ON table_2.id = table_12.id
GROUP BY table_2.authid ORDER BY total_time DESC
Ok, I have a script that grabs the user IDS and the time they spent and then puts it in mysql tables depending on which forum they have entered. The query above seems to be working fine but only for the users that have entered all forums, because the others that haven't entered in all forums don't return any result.
The ID is always the same, it is the users ID and connects is the number of times the user enters the specific forum.
If you understand my problem and know the answear please let me know, otherwise I'll try to explain better
Thanks
I think a good way to do this may be:
SELECT id, SUM(time), SUM(connects)
FROM (
SELECT id, time, connects FROM table_2
UNION ALL
SELECT id, time, connects FROM table_4
UNION ALL
SELECT id, time, connects FROM table_6
UNION ALL
SELECT id, time, connects FROM table_8
UNION ALL
SELECT id, time, connects FROM table_10
UNION ALL
SELECT id, time, connects FROM table_12
) uniontable
GROUP BY id
Since they all have the same fields.
EDIT: And it sounds like it may not be such a strange idea to merge them into one table, especially if you want to count the total time like this ;)
EDIT 2: I'm sorry, that wasn't valid SQL at all. This should be better.
Replace the INNER JOIN by a LEFT OUTER JOIN this will get you results over all the tables. You might need to re-define the SUM probably you'll get NULL on users who haven't visited all forums...
Replace the JOIN with the LEFT JOIN:
SELECT people.id, SUM(COALESCE(table_2.time, 0) + COALESCE(table_4.time, 0) + table_6.time, 0) + COALESCE(table_8.time, 0) + COALESCE(table_10.time, 0) + COALESCE(table_12.time, 0)) AS total_time,
SUM(COALESCE(table_2.connects, 0) + COALESCE(table_4.connects, 0) + COALESCE(table_6.connects, 0) + COALESCE(table_8.connects, 0) + COALESCE(table_10.connects, 0) + COALESCE(table_12.connects, 0)) AS total_connects
FROM people p
LEFT JOIN
table_2
ON table_2.id = people.id
LEFT JOIN
table_4
ON people.id = table_4.id
LEFT JOIN
table_6
ON people.id = table_6.id
LEFT JOIN
table_8
ON people.id = table_8.id
LEFT JOIN
table_10
ON people.id = table_10.id
LEFT JOIN
table_12
ON people.id = table_12.id
GROUP BY
people.authid
ORDER BY
total_time DESC
#afonso: I think you should populate all those time tables whenever a new user is created by inserting the user with a time of 0 (just so that they're in the table). Would this be an acceptable compromise for your application just to have those users in the tables so your initial query will work?
You will need to use outer joins and you will need to use IFNULL or something similar to map the "user wasn't in forum" nulls to zeroes.
SELECT t2.id,
SUM(IFNULL(t2.time, 0) + IFNULL(t4.time, 0) +
IFNULL(t6.time, 0) + IFNULL(t8.time, 0) +
IFNULL(t10.time, 0) + IFNULL(t12.time, 0)) AS total_time,
SUM(IFNULL(t2.connects, 0) + IFNULL(t4.connects, 0) +
IFNULL(t6.connects, 0) + IFNULL(t8.connects, 0) +
IFNULL(t10.connects, 0) + IFNULL(t12.connects, 0)) AS total_connects
FROM table_2 AS t2
LEFT JOIN table_4 AS t4 ON t2.id = t4.id
LEFT JOIN table_6 AS 76 ON t2.id = t6.id
LEFT JOIN table_8 AS t8 ON t2.id = t8.id
LEFT JOIN table_10 AS t10 ON t2.id = t10.id
LEFT JOIN table_12 AS t12 ON t2.id = t12.id
GROUP BY t2.id ORDER BY total_time DESC
This almost works; it does work for all users that visit the forum for which the information is stored in table_2. To make it work for people who don't visit the 'table_2 forum', the query needs to use the table that defines users and do the outer joins with that table:
SELECT u.id,
SUM(IFNULL(t2.time, 0) + IFNULL(t4.time, 0) +
IFNULL(t6.time, 0) + IFNULL(t8.time, 0) +
IFNULL(t10.time, 0) + IFNULL(t12.time, 0)) AS total_time,
SUM(IFNULL(t2.connects, 0) + IFNULL(t4.connects, 0) +
IFNULL(t6.connects, 0) + IFNULL(t8.connects, 0) +
IFNULL(t10.connects, 0) + IFNULL(t12.connects, 0)) AS total_connects
FROM Users AS u
LEFT JOIN table_2 AS t2 ON u.id = t2.id
LEFT JOIN table_4 AS t4 ON u.id = t4.id
LEFT JOIN table_6 AS 76 ON u.id = t6.id
LEFT JOIN table_8 AS t8 ON u.id = t8.id
LEFT JOIN table_10 AS t10 ON u.id = t10.id
LEFT JOIN table_12 AS t12 ON u.id = t12.id
GROUP BY u.id ORDER BY total_time DESC
However, given the symmetry of the table_N tables, I think you should do as Spiny Norman
suggests and redesign your schema so that there is one table that stores the timing and connection values:
CREATE TABLE ForumUsage
(
ForumID INTEGER NOT NULL REFERENCES Forums,
UserID INTEGER NOT NULL REFERENCES Users,
Time INTEGER NOT NULL,
Connects INTEGER NOT NULL
);
Then you sum over the entries in that table.