I am trying to coalesce on the roll up (against the year revenue), The roll up is calculating correctly, however instead of inputting 'Grand Total' at the end of the table, 'Socks' is being inputted again.
Any ideas what i am doing wrong?
select coalesce(product_name, 'total') as product_name, sum(price) as year_revenue
from orders
join product on orders.ProductID = product.ProductID
group by month(order_data) with rollup;
'Blue Shirt', '69.93'
'Denim Jeans', '197.91'
'White Blazer', '94.97'
'Socks', '109.94'
'Skinny Jeans', '73.96'
'Mini Skirt', '31.98'
'White Blazer', '74.97'
'Black Blazer', '40.99'
'Shorts', '19.98'
'Mini Skirt', '85.96'
'Flare Blouse', '33.98'
'Socks', '7.98'
'Socks', '842.55'
The reason for this is that you are grouping by MONTH(order_data), not product_name. When WITH ROLLUP happens, it is the grouped by column value that gets replaced by NULL. If you were to change your query to:
SELECT MONTH(order_data) AS month, product_name, SUM(price) AS year_revenue
FROM orders
JOIN product ON orders.ProductID = product.ProductID
GROUP BY month WITH ROLLUP
You would see the NULL values in the month column.
To achieve what you want, try changing your query to this:
SELECT IF(month IS NULL, 'Total', product_name) AS product_name, year_revenue
FROM (SELECT MONTH(order_data) as month, product_name, SUM(price) AS year_revenue
FROM orders
JOIN product ON orders.ProductID = product.ProductID
GROUP BY month WITH ROLLUP)
Related
I have 3 tables: training_schedules, training_discounts, and agents.
training_schedules: id, name, agent_id, price.
training_discounts: id, agent_id, schedule_id, discount.
agents: id, name
I try to subtract the price from training_schedules table with the discount column in training_discounts table like this:
SELECT ts.id, name, training_types, DATE_FORMAT(date_start ,'%d/%m/%Y') as date_start,
DATE_FORMAT(date_end ,'%d/%m/%Y') as date_end, quota, price, td.discount,
CASE price WHEN td.agent_id = 2 THEN (price - td.discount) ELSE price END as total
FROM training_schedules ts
LEFT JOIN training_discounts td on ts.id = td.schedule_id GROUP BY td.schedule_id;
But it doesn't right, the total column is still the same price as before even if agent_id is the same. What can possibly be wrong with my query? Here's the SQLfiddle if needed: http://sqlfiddle.com/#!9/0cd42d/1/0
You don't need to use group by since you are not using any aggregation functions.
SELECT ts.id
, name
, training_types
, DATE_FORMAT(date_start ,'%d/%m/%Y') as date_start
, DATE_FORMAT(date_end ,'%d/%m/%Y') as date_end
, quota, price
, td.discount
, CASE WHEN td.agent_id = 2 THEN price - td.discount ELSE price END as total
FROM training_schedules ts
LEFT JOIN training_discounts td on ts.id = td.schedule_id;
You are also using the select case wrongly. Another option is to use mysql if() function.
if(agent_id = 2, price - td.discount, price) as total
I have employee_id,status and payment field. I need to produce two different output ( sum(payment)) with two different condition.
The problem is when i use group by, it produce the total sum of all rows, whilst I want it to group by the employee id.
this is my query:
select employee_id,
(select sum(payment) from tblempay where status=1) AS 'Total 1',
(select sum(payment) from tblempay where status=2) AS 'Total 2'
from tblempay
group by employee_id
hope somebody can help me. Thank you.
Try this;)
select employee_id,
sum(if(status=1, payment, 0)) AS `Total 1`,
sum(if(status=2, payment, 0)) AS `Total 2`
from tblempay
group by employee_id
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
I need to list each order, list the order ID, order date, customer ID, customer first name, customer last name, sales rep ID, sales rep first name, and sales rep last name; sort by order ID; Format the order date as “mm/dd/yy”.
Here is my UPDATED Code!
SELECT Order_ID as Order_ID, to_char(Order_Date, 'mm/dd/yyyy') as Date, OR.Cust_ID as Cust_ID,
Cust_FName as Cust_FName, Cust_LName as Cust_LName, SR.Sales_Rep_ID as Sales_Rep_ID,
Sales_Rep_FName as Sales_Rep_FName, Sales_Rep_LName as SalesRepLName
FROM ORDER_arb OR, CUSTOMER_arb C, SALES_REP_arb SR
WHERE OR.Cust_ID = C.Cust_ID AND
C.Sales_Rep_ID = SR.Sales_Rep_ID
ORDER BY Order_ID;
I am receiving this error:
UPDATE!!
Error at Line 1: FROM keyword not found where expected
I would appreciate any input.
Thanks
Try this. Please change 'OR' to 'ORD' and 'as Date' to 'as OrderDate'.
Because DATE is a keyword in oracle. and OR alias seems working different than wen think. If you still needs to use column alias sa Date, please use with double quotes as "Date"
SELECT ORD.Order_ID as Order_ID, to_char(ORD.Order_Date, 'mm/dd/yyyy') as OrderDate, ORD.Cust_ID as Cust_ID,
C.Cust_FName as Cust_FName, C.Cust_LName as Cust_LName, SR.Sales_Rep_ID as Sales_Rep_ID,
SR.Sales_Rep_FName as Sales_Rep_FName, SR.Sales_Rep_LName as SalesRepLName
FROM ORDER_arb ORD, CUSTOMER_arb C, SALES_REP_arb SR
WHERE ORD.Cust_ID = C.Cust_ID
AND C.Sales_Rep_ID = SR.Sales_Rep_ID
ORDER BY Order_ID;
I am having trouble writing this query.
I need to get the current number of orders that were shipped in consecutive months.
Example: if the current month is November and they placed orders in July, August, September, October, November, it would return 5 for that user. If they didn't place an order in November, it would return 0 because their streak is broken.
The tables I'm concerned with are customer, order, and date.
Use a cross join between the date table and the customer table to get a row for every customer / month combination and then left join that against the order table to get the details, using group by to get the counts.
Something like this, although you will need to modify it to cope with the column names being reserved words.
SELECT customer.name, month.name, COUNT(order.id)
FROM customer
CROSS JOIN date
LEFT OUTER JOIN order
ON customer.id = order.customer_id
AND MONTH(date.date) = MONTH(order.date)
WHERE date.date BETWEEN startofdaterange AND endofdaterange
GROUP BY customer.name, month.name
Or if I have misread the question, and you need a count of the orders if they order every month in the range, or 0 if they skipped a month then something like this (not tested so expect a typo or 2, would need the table def to test):-
SELECT name, CASE WHEN MonthCount = MonthOrderCount THEN OrderCount ELSE 0 END AS ContinuousOrderMonths
FROM (
SELECT CustName, COUNT(MonthName) AS MonthCount, SUM(MonthOrderCount) AS OrderCount, SUM(CASE WHEN MonthOrderCount > 0 THEN 1 ELSE 0 END)
FROM (
SELECT customer.name AS CustName, month.name AS MonthName, COUNT(order.id) AS MonthOrderCount
FROM customer
CROSS JOIN date
LEFT OUTER JOIN order
ON customer.id = order.customer_id
AND MONTH(date.date) = MONTH(order.date)
WHERE date.date BETWEEN startofdaterange AND endofdaterange
GROUP BY customer.name, month.name )Sub1 ) Sub2
GROUP BY CustName
If you want a list of customers and a comma separated list of orders per month:-
SELECT CustName, GROUP_CONCAT(CAST(MonthsOrder AS CHAR))
FROM (
SELECT customer.name AS CustName, month.name, COUNT(order.id) AS MonthsOrder
FROM customer
CROSS JOIN date
LEFT OUTER JOIN order
ON customer.id = order.customer_id
AND MONTH(date.date) = MONTH(order.date)
WHERE date.date BETWEEN startofdaterange AND endofdaterange
GROUP BY customer.name, month.name) Sub1
GROUP BY CustName
You might have to expand this to get the month name with each one and force the order
Here you replace now and static date as per columnname :
select (case
when (month(now())=11 and
(month('2012-02-02')>=7 and month('2012-02-02')<=11))
then 5
else
0 end) as 'month'
from tablename