I keep getting an invalid use of group function. I'm looking to sum the values of one table and return the answer to the original table. I will be using this in a trigger.
But I keep getting an invalid use of group function 1111
UPDATE `Order`
INNER JOIN orderitem
ON order.OrderID = orderitem.OrderId
SET Order.TotalAmmount = SUM(orderitem.UnitPrice)
WHERE orderitem.OrderitemId = order.OrderId
Use a sub-query to aggregate:
UPDATE `Order`
SET `Order`.TotalAmmount =
(SELECT SUM(UnitPrice)
FROM orderitem
WHERE OrderitemId = `Order`.OrderId)
You can't use an aggregated result directly in a set value (because the level of aggregation between the result and each row of the table is not the same)
you should use an inner join on subquery for aggregated result and use the result for the subquery
UPDATE `Order`
INNER JOIN (
select orderitemID, SUM(orderitem.UnitPrice) sum_price
from orderitem
group by orderitemID
) t on t.orderitemID = order.OrderId
SET Order.TotalAmmount = t.sum_price
Related
im using a query that checks for duplicate values, but now i want it to do the opposite of this query:
SELECT * FROM orders WHERE buy_date (SELECT buy_date FROM orders GROUP BY buy_date HAVING count(*)>1)
Result:
I tried changing HAVING count(*)=0 / HAVING count(*)<1 put it returns nothing
The limiting clause having count(*) < 1 will not return values. You cannot return a recordset with half a row! Try HAVING count(*) < 2 which will return rows with a count of 1.
You may also want to check out the DISTINCT function which returns distinct values.
I suppose you consider duplicate two orders with the same buy_date and different id (I suppose id is the name of PK field)
For duplicate - try this:
SELECT o1.*
FROM orders o1
WHERE EXISTS(
SELECT 'duplicate'
FROM orders o2
WHERE o1.id <> o2.id
AND o1.buy_date = o2.buy_date
)
For single - try this:
SELECT o1.*
FROM orders o1
WHERE NOT EXISTS(
SELECT 'duplicate'
FROM orders o2
WHERE o1.id <> o2.id
AND o1.buy_date = o2.buy_date
)
Having Count > 1 returns duplicates as you said. Having Count = 1 will return non duplicates.
Shouldn't it be count(*) = 1?
If you have count(*) = 0 it means that you select only those record that do not exist... so it correctly returns nothing.
Or if you want to be mathematically correct, negation of sth>1 is sth<=1
I have a weird situation. I need to select all data from table name with distinct values from other table.
Here is database scheme of database that I need to get distinct values:
When I run both queries without INNER JOIN they run without error but when I use INNER JOIN I got error
This is query that I used:
SELECT * FROM `todo`
INNER JOIN
SELECT `task`.`status`,COUNT(*) as count FROM `task`
ON `todo`.`id`=`task`.`id_list` WHERE `todo`.`user_id` = 43
As you can see I need to get total count of status column from other table. Can it be done using one single query or do I need to run two querys to get data...
You need to wrap the join In parenthesis
SELECT td.*, t.*
FROM `todo` td
JOIN
( SELECT `status`, SUM(status=0) as status_0, SUM(status=1) as status_1 , id_list
FROM `task`
GROUP BY id_list
) t ON td.id= t.id_list
WHERE td.user_id = 43
You can do this in one query. Even without a subquery:
SELECT ta.status, COUNT(*) as count
FROM todo t INNER JOIN
task ta
ON t.id = ta.id_list
WHERE t.user_id = 43
GROUP BY ta.status;
EDIT:
If the above produces what you want, then you probably need:
SELECT t.*, ta.status, taa.cnt
FROM todo t INNER JOIN
task ta
ON t.id = ta.id_list INNER JOIN
(SELECT count(*) as cnt, ta.status
FROM task ta
GROUP BY ta.status
) taa
on ta.status = taa.status
WHERE t.user_id = 43 ;
You seem to want a summary at the status level, which is only in task. But you want the information at the row level for todo.
Here is my query:
UPDATE student_tests,
(SELECT SUM(olc_sta_i_points_earned) AS total, olc_sta_i_stt_num FROM student_answers
JOIN student_tests ON olc_sta_i_stt_num = olc_stt_i_num
) AS a
SET student_tests.olc_stt_i_score = a.total
WHERE a.olc_sta_i_stt_num = student_tests.olc_stt_i_num
There are no errors but it says zero rows are affected.
Basically I have two tables: student_tests and student_answers the test id is mapped to the student_answers tables. I want a subquery where I can sum all the student answers for the specific test id and then update the score column in the student_tests table in the tests table.
Am i doing something wrong with the where clause here? or is it something else?
You should phrase this as an update/join explicitly, rather than having the join condition in the where clause.
Your problem is that you have no group by in the subquery. The extra join to student_tests seems unnecessary, so try this:
UPDATE student_tests s JOIN
(SELECT SUM(a.olc_sta_i_points_earned) AS total, a.olc_sta_i_stt_num
FROM student_answers a
GROUP BY a.olc_sta_i_stt_num
) AS a
ON a.olc_sta_i_stt_num = t.olc_stt_i_num
SET s.olc_stt_i_score = a.total
I've got the following select query:
SELECT opt.product_option_id
FROM `oc_product_option_value` AS opt_val, `oc_product_option` AS opt
WHERE `opt`.`product_option_id` = `opt_val`.`product_option_id`
AND `opt_val`.`price` = '0.0000'
I thought that i could use that in an delete query:
DELETE oc_product_option, oc_product_option_value FROM oc_product_option
INNER JOIN oc_product_option_value
WHERE `oc_product_option`.`product_option_id` = `oc_product_option_value`.`product_option_id`
AND `oc_product_option_value`.`price` = '0.0000'
But that deleted ALL rows in oc_product_option. So what did i do wrong?
Can you give this a try?
DELETE t1 FROM oc_product_option t1
JOIN oc_product_option_value t2
WHERE `t1`.`product_option_id` = `t2`.`product_option_id`
AND `t2`.`price` = '0.0000'
Is it the intetion to delete the rows of both tables?
You make a circular dependence and this is why you get this result
Bellow query should delete only rows that have id in oc_product_option and price zero.
Or you have to define range of ids in oc_product_option using another criteria to filter oc_product_option table
DELETE FROM oc_product_option o
WHERE o.product_option_id in (SELECT opt.product_option_id FROM oc_product_option_value
where `oc_product_option_value`.`price` = '0.0000')
I'm trying to sync store ids on newtable with the ids from the maintable here:
UPDATE newtable t SET t.store_id = (SELECT store_id FROM maintable s
WHERE t.state = s.state AND s.city = t.city AND t.name = s.name)
Whenever a subquery returns more than one row it errors out with "Subquery returns more than 1 row", but when it returns zero rows the subquery is considered to have returned nothing so the store_id on newtable remains NULL. Nothing new here, it's just how it works.
I'd like to know if it's possible to let the subquery output the same as what it does when it has no matches when it has more than one matching row.
This way I'd get the store_id synced only for ONE matching row on the main table and skipped when more than one matching row comes out in the subquery.
I think you might be looking for a HAVING clause to force the query to match exactly once:
UPDATE newtable t
SET t.store_id = (
SELECT store_id
FROM maintable s
WHERE t.state = s.state
AND s.city = t.city
AND t.name = s.name
HAVING COUNT(*) = 1
)
That should make multiple matches behave the same as no matches. The HAVING clause is applied almost at the very end of the query process; if there are no matches from the WHERE or more than one match, then COUNT(*) = 1 will fail and the inner query will return nothing but if there is exactly one row then COUNT(*) = 1 will succeed and the inner query will return that single match.
You might consider putting a LIMIT 1 in your sub-query to better achieve what you are trying to accomplish, depending on your specific needs.
Otherwise, you should be able to get creative with IF or CASE:
UPDATE newtable t SET t.store_id = (
SELECT IF(num>1, NULL, storeid) FROM (
SELECT COUNT(*) AS num, storeid FROM maintable s WHERE t.state=s.state AND s.city=t.city AND t.name=s.name
)
)
Untested, but should get you in the ballpark.
UPDATE newtable t SET t.store_id = IFNULL((SELECT store_id FROM maintable s
WHERE t.state = s.state AND s.city = t.city AND t.name = s.name HAVING COUNT(*) = 1), t.store_id)
IFNULL(use_this_value_if_not_null,value_if_first_isnull)