Overview:Write a SELECT statement that summarizes the guitar shop’s orders
GROUP BY order_id
HAVING MAX(discount_amount)>500
ORDER BY order_id ASC
I keep getting this error message: Error code 1055. Expression #3 of select list is not
use sum(quantity) as you are using aggregated function you've to use this also in aggregated way other wise it's need to added in group by clause
SELECT order_id, COUNT(*) AS num_items, SUM(item_price - discount_amount) *
sum(quantity) AS order_total, MAX(discount_amount) AS max_item_discount
FROM order_items
GROUP BY order_id
HAVING MAX(discount_amount)>500
ORDER BY order_id ASC
use quantity in group by as your engine ONLY_FULL_GROUP_BY
SELECT order_id, COUNT(*) AS num_items, SUM(item_price - discount_amount) *
quantity AS order_total, MAX(discount_amount) AS max_item_discount
FROM order_items
GROUP BY order_id,quantity
HAVING MAX(discount_amount)>500
ORDER BY order_id ASC
other wise use quantity inside aggregation sum((item_price - discount_amount) * quantity)
You have the column quantity not in group by nut could be you need move the column inside te sum for item_price - discount_amount
SELECT order_id
, COUNT(*) AS num_items
, SUM((item_price - discount_amount) * quantity ) AS order_total
, MAX(discount_amount) AS max_item_discount
FROM order_items
GROUP BY order_id
HAVING MAX(discount_amount)>500
ORDER BY order_id ASC
Related
There is a table like this, how can I get customer_id, amount_spent, top_item out of it?
amount_spent the amount spent on all items by this customer
top_item, which displays the name of the item for which the customer has spent the most money
I have tried the following query, however I cannot output the top_1 item with it
select customer_id, sum(item_number * item_price) as amount_spent_1m
from temp
group by customer_id
Check the demo here.
You can achieve it as below :
select customer_id, sum(item_number * item_price) as amount_spent_1m,
item_name as top_item_1m
from temp
group by customer_id, item_name
order by amount_spent_1m desc;
It gives me the following result :
I am sure there is a way to do this with one less step but my brain is not seeing it right now -
SELECT customer_id, amount_spent, item_name AS top_item
FROM (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY item_total DESC) rn,
SUM(item_total) OVER (PARTITION BY customer_id) amount_spent
FROM (
SELECT customer_id, item_id, item_name, SUM(item_price * item_number) item_total
FROM table1
GROUP BY customer_id, item_id, item_name
) t1
) t2
WHERE rn = 1
db<>fiddle
I have below SQL statement to generate a total at bottom of search result but I do not want to display Total if there is no record has been found. Need help on below Statement.
SELECT Member_ID, Order_Total, Shipping_Cost, TAX FROM Order Where
Order_Total > 100
UNION (
SELECT "Total" as Member_ID, sum(Order_Total) as Order_Total, sum(Shipping_Cost) as Shipping_Cost, sum(TAX) as TAX FROM Order Where
Order_Total > 100);
You don't need UNION, you can use the WITH ROLLUP option to make an automatic total. If the query doesn't select any rows, the result will be empty.
SELECT IFNULL(Member_ID, 'Total') AS Member_ID, Order_Total, Shipping_Cost, TAX
FROM (
SELECT Member_ID, sum(Order_Total) as Order_Total, sum(Shipping_Cost) as Shipping_Cost, sum(TAX) as TAX
FROM `Order`
Where Order_Total > 100
GROUP BY Order_ID
WITH ROLLUP) AS x
Another way is to keep your UNION, but add a HAVING clause to the second query.
SELECT Member_ID, Order_Total, Shipping_Cost, TAX
FROM `Order`
Where Order_Total > 100
UNION (
SELECT "Total" as Member_ID, sum(Order_Total) as Order_Total, sum(Shipping_Cost) as Shipping_Cost, sum(TAX) as TAX
FROM `Order`
Where Order_Total > 100
HAVING COUNT(*) > 0);
I have a table with
orderNumber(pk) , customerNumber , comment
I have to count the maximum order placed by a user and show its user ID and MAX count . I have following Query
It shows the count Right but it takes the first CustomerNumber in the table
SELECT maxCount.customerNumber , MAX(`counted`) FROM
(
SELECT customerNumber, COUNT(*) AS `counted`
FROM `orders`
GROUP BY `customerNumber`
)as maxCount
Thanks & regards
Just use ORDER BY with your inner query:
SELECT customerNumber, COUNT(*) AS `counted`
FROM `orders`
GROUP BY `customerNumber`
ORDER BY COUNT(*) DESC
LIMIT 1
If you want to return all customer numbers in the event of a tie, you can use a HAVING clause with a subquery which identifies the maximum count:
SELECT customerNumber, COUNT(*) AS counted
FROM orders
GROUP BY customerNumber
HAVING COUNT(*) = (SELECT MAX(t.counted) FROM (SELECT COUNT(*) AS counted
FROM orders
GROUP BY customerNumber) t)
Demo here:
SQLFiddle
I am trying to create a dashboard with customer ID and dates of 1st, 2nd and 3rd purchases. I use MySQL, Northwind db.
My query works perfectly fine for the 1st purchase, but I do not understand how to find 2nd and 3rd purchase date for each customer.
Now I'm trying to do next: 2nd_purchase_date is the next MIN(OrderDate) after 1st_purchase_date but I get following error 'Invalid use of group function'
DROP TABLE IF EXISTS t1;
CREATE TABLE t1
(
CustomerID varchar(5),
OrderDate datetime,
OrderID int,
i int
);
INSERT INTO t1(CustomerID, OrderDate, OrderID, i)
SELECT CustomerID, min(OrderDate), min(OrderID),1
FROM Orders
GROUP BY CustomerID;
INSERT INTO t1(CustomerID, OrderDate, OrderID, i)
SELECT CustomerID,min(OrderDate), min(OrderID),2
FROM Orders
WHERE min(OrderDate)
NOT IN
(
SELECT CustomerID, min(OrderDate), min(OrderID)
FROM Orders
)
GROUP BY CustomerID;
INSERT INTO t1(CustomerID, OrderDate, OrderID, i)
SELECT CustomerID,min(OrderDate), OrderID,3
FROM Orders
WHERE min(OrderDate)
NOT IN
(
SELECT CustomerID, min(OrderDate), min(OrderID) FROM Orders
)
GROUP BY CustomerID;
As shown in the last example here, you can use the LIMIT offset, count feature in combination with ORDER BY column ASC to select the entry with the second purchase date for a single user (with the id XXX replaced with the respective value):
SELECT CustomerID, OrderDate, OrderID
FROM Orders
WHERE CustomerID = XXX
ORDER BY OrderDate ASC
LIMIT 1, 1;
or the entry with the third purchase date:
SELECT CustomerID, OrderDate, OrderID
FROM Orders
WHERE CustomerID = XXX
ORDER BY OrderDate ASC
LIMIT 2, 1;
... and so on.
You get the first entry via
SELECT CustomerID, OrderDate, OrderID
FROM Orders
WHERE CustomerID = XXX
ORDER BY OrderDate ASC
LIMIT 0, 1;
or the equivalent:
SELECT CustomerID, OrderDate, OrderID
FROM Orders
WHERE CustomerID = XXX
ORDER BY OrderDate ASC
LIMIT 1;
This should give you the first three orders for a single customer:
SELECT CustomerID, OrderDate, OrderID
FROM Orders
WHERE CustomerID = XXX
ORDER BY OrderDate ASC
LIMIT 3;
While the following is definitely not good from a performance perspective, it should still work to give you the first three orders for each customer:
SELECT o1.CustomerID, o1.OrderDate, o1.OrderID
FROM Orders o1
WHERE o1.OrderID IN
(SELECT o2.OrderID
FROM Orders o2
WHERE o1.CustomerID = o2.CustomerID
ORDER BY o2.OrderDate ASC LIMIT 3)
ORDER BY o1.CustomerID, o2.OrderDate ASC;
SQL Fiddle
Table scheme:
CREATE TABLE company
(`company_id` int,`name` varchar(30))
;
INSERT INTO company
(`company_id`,`name`)
VALUES
(1,"Company A"),
(2,"Company B")
;
CREATE TABLE price
(`company_id` int,`price` int,`time` timestamp)
;
INSERT INTO price
(`company_id`,`price`,`time`)
VALUES
(1,50,'2015-02-21 02:34:40'),
(2,60,'2015-02-21 02:35:40'),
(1,70,'2015-02-21 05:34:40'),
(2,120,'2015-02-21 05:35:40'),
(1,150,'2015-02-22 02:34:40'),
(2,130,'2015-02-22 02:35:40'),
(1,170,'2015-02-22 05:34:40'),
(2,190,'2015-02-22 05:35:40')
I'm using Cron Jobs to fetch company prices. In concatenating the price history for each company, how can I make sure that only the last one in each day is included? In this case, I want all of the price records around 05:30am concatenated.
This is the result I'm trying to get (I have used Date(time) to only get the dates from the timestamps):
COMPANY_ID PRICE TIME
1 70|170 2015-02-21|2015-02-22
2 120|190 2015-02-21|2015-02-22
I have tried the following query but it doesn't work. The prices don't correspond to the dates and I don't know how to exclude all of the 2:30 am records before applying the Group_concat function.
SELECT company_id,price,trend_date FROM
(
SELECT company_id, GROUP_CONCAT(price SEPARATOR'|') AS price,
GROUP_CONCAT(trend_date SEPARATOR'|') AS trend_date
FROM
(
SELECT company_id,price,
DATE(time) AS trend_date
FROM price
ORDER BY time ASC
)x1
GROUP BY company_id
)t1
Can anyone show me how to get the desired result?
Ok, so this should work as intended:
SELECT p.company_id,
GROUP_CONCAT(price SEPARATOR '|') as price,
GROUP_CONCAT(PriceDate SEPARATOR '|') as trend_date
FROM price as p
INNER JOIN (SELECT company_id,
DATE(`time`) as PriceDate,
MAX(`time`) as MaxTime
FROM price
GROUP BY company_id,
DATE(`time`)) as t
ON p.company_id = t.company_id
AND p.`time` = t.MaxTime
GROUP BY p.company_id
Here is the modified sqlfiddle.
This is a bit unorthodox but I think it solves your problem:
SELECT company_id,
GROUP_CONCAT(price SEPARATOR'|'),
GROUP_CONCAT(trend_date SEPARATOR'|')
FROM (
SELECT *
FROM (
SELECT company_id,
DATE(`time`) `trend_date`,
price
FROM price
ORDER BY `time` DESC
) AS a
GROUP BY company_id, `trend_date`
) AS b
GROUP BY company_id