SQL update table using result of another query - mysql

I am trying to update the table(orders)after calculate the total amount of that order, I successfully calculate the total amount, but I cannot find way to update the table using the result.
code I successfully calculate the total amount:
SELECT orders.orderid,
SUM(ordersdish.quantity*dish.price) AS total
FROM dish
JOIN ordersdish
ON ordersdish.dishid = dish.dishid
JOIN orders
ON orders.orderid = ordersdish.orderid
GROUP BY orders.orderid;
Result:
total amount
Code I tried to update table(orders):
UPDATE orders
SET total = t1.total
FROM (
SELECT orders.orderid,
SUM(ordersdish.quantity*dish.price) AS total
FROM dish
JOIN ordersdish
ON ordersdish.dishid = dish.dishid
JOIN orders
ON orders.orderid = ordersdish.orderid
GROUP BY orders.orderid
)t1
WHERE orders.orderid = t1.orderid;
MySQL said:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'from
(select orders.orderid, SUM(ordersdish.quantity*dish.price)as total
from ' at line 3
And here is the table "orders":

The correct syntax in MySQL use JOIN:
update orders o join
(select od.orderid, SUM(od.quantity * d.price)as total
from dish d join
ordersdish od
on od.dishid = d.dishid
group by od.orderid
) t1
on o.orderid = t1.orderid
set o.total = t1.total;
Note that orders is not needed in the subquery, because the orderid is in orderdish.

Please try this answer.
UPDATE o
SET o.total = t1.total
(SELECT o.orderid, SUM(od.quantity * d.price) AS total
FROM dish AS d
JOIN ordersdish AS od ON od.dishid = d.dishid
JOIN orders AS o ON o.orderid = od.orderid
GROUP BY orders.orderid) t1
WHERE o.orderid = t1.orderid;

Related

The output of MySQL results shows no results in one column

Whenever I use this query:
SELECT Orders.SKU AS SKU,
(COUNT(*) * 100 / (SELECT COUNT(*) FROM Orders INNER JOIN RMA ON Orders.OrderID = RMA.OrderID)) AS Returned_Percentage
FROM Orders
INNER JOIN RMA
ON Orders.OrderID = RMA.OrderID
INNER JOIN Customers
ON Customers.CustomerID = Orders.CustomerID
GROUP BY SKU, Description
ORDER BY Returned_Percentage DESC
I get the results that I need.
Successful Results
But when I add a column with a larger VARCHAR(50), the results leave out one column of results.
SELECT Orders.SKU AS SKU,
(COUNT(*) * 100 / (SELECT COUNT(*) FROM Orders INNER JOIN RMA ON Orders.OrderID = RMA.OrderID)) AS Returned_Percentage, **Orders.Description**
FROM Orders
INNER JOIN RMA
ON Orders.OrderID = RMA.OrderID
INNER JOIN Customers
ON Customers.CustomerID = Orders.CustomerID
GROUP BY SKU, Description
ORDER BY Returned_Percentage DESC
enter image description here
Can anyone point me in the right direction to obtaining the results with the records stored properly in the columns?
Thank you!
I add the query:
SELECT Orders.SKU AS SKU,
(COUNT(*) * 100 / (SELECT COUNT(*) FROM Orders INNER JOIN RMA ON Orders.OrderID = RMA.OrderID)) AS Returned_Percentage, Orders.Description
FROM Orders
INNER JOIN RMA
ON Orders.OrderID = RMA.OrderID
INNER JOIN Customers
ON Customers.CustomerID = Orders.CustomerID
GROUP BY SKU, Description
ORDER BY Returned_Percentage DESC
but receive empty columns of records.

using MYSQL Group By to get the most popular value

I am practicing MYSQL using https://www.w3schools.com/mysql/trymysql.asp?filename=trysql_func_mysql_concat which has a mock database for me to practice with an I am experimenting using the GROUP BY command I am attempting to group all employees up with all of their sales and determine, their name, their amount of sales and the product that they sold the most. I have managed to get their name and sales but not the product name. I know that extracting information with a group by is difficult and I have tried using a sub query. Is there a way to get the information.
My query is below.
SELECT
CONCAT_WS(' ',
Employees.FirstName,
Employees.LastName) AS 'Employee name',
COUNT(*) AS 'Num of sales'
FROM
Orders
INNER JOIN
Employees ON Orders.EmployeeID = Employees.EmployeeID
INNER JOIN
OrderDetails ON OrderDetails.OrderID = Orders.OrderID
INNER JOIN
Products ON Products.ProductID = OrderDetails.ProductID
GROUP BY Orders.EmployeeID
ORDER BY COUNT(*) DESC;
What this says is get orders, join employees based on orders employeeid, join the order details based on order id and join products information based on product id in the order details, then it groups them by the employee id and orders them by the number of sales an employee has made.
SELECT
concat_ws(' ',
Employees.FirstName,
Employees.LastName) as 'Employee name',
count(*) as 'Num of sales',
(
SELECT Products.ProductName
FROM Orders
INNER JOIN Employees ON Orders.EmployeeID = Employees.EmployeeID
INNER JOIN OrderDetails ON OrderDetails.OrderID = Orders.OrderID
INNER JOIN Products ON Products.ProductID = OrderDetails.ProductID
GROUP BY Orders.EmployeeID
ORDER BY count(Products.ProductName) desc
LIMIT 1
) as 'Product Name'
FROM Orders
INNER JOIN Employees ON Orders.EmployeeID = Employees.EmployeeID
INNER JOIN OrderDetails ON OrderDetails.OrderID = Orders.OrderID
INNER JOIN Products ON Products.ProductID = OrderDetails.ProductID
GROUP BY Orders.EmployeeID
ORDER BY count(*) desc;
Above is my attempt at using a sub query for the solution.
It is quite ugly, as the w3school uses still mysql 5.7
On a personal note, you should install your own server grab somewhere a database and test it there, in mysql workbench you can have many query tabs in which you can test queries , till you het the "right" result.
SELECT
CONCAT_WS(' ',
Employees.FirstName,
Employees.LastName) AS 'Employee name',
COUNT(*) AS 'Num of sales',
tn.ProductName
FROM
Orders
INNER JOIN
Employees ON Orders.EmployeeID = Employees.EmployeeID
INNER JOIN
OrderDetails ON OrderDetails.OrderID = Orders.OrderID
INNER JOIN
Products ON Products.ProductID = OrderDetails.ProductID
INNEr JOIN
(SELECT EmployeeID, p.ProductName
FROM (SELECT IF (#Eid = EmployeeID ,#rn := #rn +1, #rn := 1) rn,ProductID, sumamount
, #Eid := EmployeeID as EmployeeID
FROM
(
SELECT
EmployeeID,ProductID, SUM(Quantity) sumamount
FROM Orders o INNER JOIN OrderDetails od ON od.OrderID = o.OrderID,(SELECT #Eid := 0, #rn := 0) t1
GROUP BY EmployeeID,ProductID
ORDER BY EmployeeID,sumamount DESC ) t2 ) t3
INNER JOIN Products p ON t3.ProductID = p.ProductID
WHERE rn= 1) tn
ON Orders.EmployeeID = tn.EmployeeID
GROUP BY Orders.EmployeeID
ORDER BY COUNT(*) DESC;
In your second query you are trying to get an employee's most often sold product. But there are two mistakes in that subquery:
The subquery is invalid. You group by employee, but select a product. Which product? An employee can sell many different products. MySQL should raise a syntax error here, as all other DBMS I know of do. But you are in cheat mode. MySQL allows incorrect aggregation queries and silently applies ANY_VALUE on all columns that cannot be selected otherwise. Thus you are selecting ANY_VALUE(Products.ProductName), i.e. a product arbitrarily chosen by the DBMS. To get out of cheat mode SET sql_mode = 'ONLY_FULL_GROUP_BY';.
Then, you don't relate the subquery to your main query. So when selecting the row for, say, employee #123, your subquery still selects data for all employees in order to pick one of their products. And as this is independent from the employee in the main query, it will probably pick the same product for every other employee you are selecting, too.
Here is what the query should look like instead:
SELECT
concat_ws(' ', e.FirstName, e.LastName) as "Employee name",
count(*) as "Num of sales",
(
SELECT p2.ProductName
FROM Orders o2
INNER JOIN OrderDetails od2 ON od2.OrderID = o2.OrderID
INNER JOIN Products p2 ON p2.ProductID = od2.ProductID
WHERE o2.EmployeeID = o.EmployeeID
GROUP BY p2.ProductID
ORDER BY count(*) DESC
LIMIT 1
) as "Product Name"
FROM Orders o
INNER JOIN Employees e ON o.EmployeeID = e.EmployeeID
INNER JOIN OrderDetails od ON od.OrderID = o.OrderID
GROUP BY o.EmployeeID
ORDER BY count(*) desc;
Demo: https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=f35e96764d454a4032d7778b550fc6b4
Disclaimer: When an employee sold more than one product most often (e.g. 500 x product A, 500 x product B, 200 x product C), then one of them (A or B in the example) gets picked arbitrarily for the employee.

mysql #1242 - Subquery returns more than 1 row

This is for my thesis and the dead end is later i don't know what i do wrong here .. Im hoping that someone can help me to know what's wrong here thanks
SELECT
flower_id,
flower_name,
flower_description,
flower_price,
flower_category,
(quantity - (SELECT
SUM(q.quantity_value)
FROM
orders_details od
INNER JOIN
cart_details cd ON cd.cart_id = od.cart_id
INNER JOIN
quantities q ON q.quantity_id = cd.quantity_id
WHERE
od.flag = 1 AND cd.flower_id = flower_id
GROUP BY cd.flower_id)) AS 'quantity',
mfg_date,
exp_date
FROM
flower_details,
categories
WHERE
flower_details.flower_category = categories.category_id
What im doing here is getting the total quantity of products from customer bought minus to inventory stocks
If your subselect return more then a rows you should join the sum using an inner join on subselect
If your subselect return more then a rows you should join the sum using an inner join on subselect inner join on subselect
SELECT
flower_details.flower_id,
flower_name,
flower_description,
flower_price,
flower_category,
flower_details.quantity - t1.quantity,
mfg_date,
exp_date
FROM flower_details
INNER JOIN categories ON flower_details.flower_category = categories.category_id
INNER JOIN (
SELECT cd.flower_id ,
SUM(q.quantity_value) AS quantity
FROM
orders_details od
INNER JOIN
cart_details cd ON cd.cart_id = od.cart_id
INNER JOIN
quantities q ON q.quantity_id = cd.quantity_id
WHERE
od.flag = 1 AND cd.flower_id = flower_id
GROUP BY cd.flower_id
) t1 on flower_details.flower_id = t1.flower_id

Another 1064 syntax error

I just can't figure out what's wrong with this syntax. I get a #1064 syntax error at the last line.
SELECT b.id, b.lastname, b.name, c.balance, a.maxdebt, b.warndata, b.warndownload, b.warnupload, b.warndebt, b.cutoffdata, b.cutoffdownload, b.cutoffupload, b.cutoffdebt, b.data, b.download, b.upload, b.warning, b.access, b.cutoffstop
FROM (
SELECT customers.id AS id, SUM(tariffs.value) AS maxdebt
FROM tariffs
INNER JOIN assignments ON tariffs.id = assignments.tariffid
INNER JOIN customers ON assignments.customerid = customers.id
GROUP BY id
) a
LEFT JOIN (
SELECT customers.id AS id, UPPER(lastname) AS lastname, customers.name AS name, SUM(stats.upload+stats.download) AS data, SUM(stats.download) AS download, SUM(stats.upload) AS upload, cutoffstop, warndata, warndownload, warnupload, warndebt, cutoffdata, cutoffdownload, cutoffupload, cutoffdebt, warning, access
FROM customers
LEFT JOIN nodes ON customers.id = nodes.ownerid
LEFT JOIN stats ON nodes.id = stats.nodeid
LEFT JOIN customerwarnings ON customers.id = customerwarnings.id
GROUP BY id
) b
LEFT JOIN (
SELECT customerid, SUM(cash.value) AS balance
FROM cash
GROUP BY customerid
) c ON a.id = b.id = c.customerid
I've tried to join the tables with RIGHT and LEFT JOINS to see if there is a difference, but they give me the same error.
The different queries within work fine on themselves, but when I join them together in this query I get a syntax error. Does anyone have an idea what I should or shouldn't do?
The error: "#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 21"
Here is the reference for Multiple LEFT JOIN
SELECT b.id, b.lastname, b.name, c.balance, a.maxdebt, b.warndata, b.warndownload, b.warnupload, b.warndebt, b.cutoffdata, b.cutoffdownload, b.cutoffupload, b.cutoffdebt, b.data, b.download, b.upload, b.warning, b.access, b.cutoffstop
FROM (
SELECT customers.id AS id, SUM(tariffs.value) AS maxdebt
FROM tariffs
INNER JOIN assignments ON tariffs.id = assignments.tariffid
INNER JOIN customers ON assignments.customerid = customers.id
GROUP BY id
) a
LEFT JOIN (
SELECT customers.id AS id, UPPER(lastname) AS lastname, customers.name AS name, SUM(stats.upload+stats.download) AS data, SUM(stats.download) AS download, SUM(stats.upload) AS upload, customers.cutoffstop, warndata, warndownload, warnupload, warndebt, cutoffdata, cutoffdownload, cutoffupload, cutoffdebt, nodes.warning, nodes.access
FROM customers
LEFT JOIN nodes ON customers.id = nodes.ownerid
LEFT JOIN stats ON nodes.id = stats.nodeid
LEFT JOIN customerwarnings ON customers.id = customerwarnings.id
GROUP BY id
) b ON a.id = b.id
LEFT JOIN (
SELECT customerid, SUM(cash.value) AS balance
FROM cash
GROUP BY customerid
) c ON a.id = c.customerid

MySQL , JOIN , When total = 1

i need little help in writing the MYSQL Query.
i want to retreive the data from 3 tables, but i want to retreive the data from 3rd table only if the count() value is equals to 1.
please see the below query.
SELECT count(orderdetails.orderId) as total,gadgets.*,orders.* FROM orders
JOIN orderdetails ON orders.orderId = orderdetails.orderId
CASE total WHEN 1 THEN (JOIN gadgets ON gadgets.gadgetId = orders.gadgetId)
GROUP BY orders.orderId
ORDER BY orders.orderId DESC;
mysql always gives me an error, and i couldnt find any solution over internet.
Just add a Simple Condition in Join, and it would work (Of course you have make it Left Join).
SELECT count(orderdetails.orderId) as total,gadgets.*,orders.* FROM orders
JOIN orderdetails ON orders.orderId = orderdetails.orderId
LEFT JOIN gadgets ON gadgets.gadgetId = orders.gadgetId
and total=1 --Simple Logic
GROUP BY orders.orderId
ORDER BY orders.orderId DESC;
SELECT
g.*, o.*
FROM
orders AS o
JOIN
( SELECT orderId
FROM orderdetails
GROUP BY orderId
HAVING COUNT(*) = 1
) AS od
ON o.orderId = od.orderId
JOIN gadgets AS g
ON g.gadgetId = o.gadgetId
ORDER BY
o.orderId DESC ;
You can join the table and get only results having total = 1
SELECT count(orderdetails.orderId) as total,gadgets.*,orders.* FROM orders
JOIN orderdetails ON orders.orderId = orderdetails.orderId
JOIN gadgets ON gadgets.gadgetId = orders.gadgetId
GROUP BY orders.orderId
HAVING total = 1
ORDER BY orders.orderId DESC;
HTH