I have a table having structure as follows
id cust_id target month year fiscal_ID
1 234 50 4 2013 1
2 234 50 5 2013 1
3 234 50 6 2013 1
4 234 150 7 2013 1
5 234 150 8 2013 1
6 234 150 9 2013 1
I need to get the result as follows
cust_id target quarter year fiscal_ID
234 150 Q1 2013 1
234 450 Q2 2013 1
months 4,5,6 in Q1, 7,8,9 in Q2 etc
Since you are storing the month and year in separate columns, one way you can get the result is to use a derived table that references the month and quarter and you join to that data:
select t.cust_id,
sum(target) target,
d.qtr,
t.year,
t.fiscal_id
from yourtable t
inner join
(
select 4 mth, 'Q1' qtr union all
select 5 mth, 'Q1' qtr union all
select 6 mth, 'Q1' qtr union all
select 7 mth, 'Q2' qtr union all
select 8 mth, 'Q2' qtr union all
select 9 mth, 'Q2'
) d
on t.month = d.mth
group by t.cust_id, d.qtr, t.year, t.fiscal_id;
See SQL Fiddle with Demo.
Related
I have 1 table named ItemDelivery. I wanted to get the count of items that has DeliveryDate and the items that has been receivedDate per month. Some items deliveryDate month have different receiveDate month such as items scheduled for delivery on the later part of the month would be received on early days of succeeding month. Some may take months to be delivered for overseas.
This is the data:
id iditem deliveryDate receiveDate
1 2 2021-01-03 2021-01-05
2 2 2021-01-03
3 3 2021-02-05 2021-02-06
4 5 2021-02-05
5 4 2021-02-20 2021-03-01
6 3 2021-03-15 2021-04-08
I would like to have
Mo Delivery Recieve
Jan 2 1
Feb 3 1
Mar 1 1
Apr 0 1
This query gives 1 columns only
select date_format(deliveryDate,'%b') as mo ,
count(id) as delivery
from ItemDelivery
where year(deliveryDate)=2021
group by month(deliveryDate)
union all
select date_format(receiveDate,'%b') as mo ,
count(id) as received
from ItemDelivery
where year(receiveDate)=2021
group by month(receiveDate)
Output:
Mo Delivery
Jan 2
Feb 3
Mar 1
Jan 1
Feb 1
Mar 1
Apr 1
This query also have different output
SELECT d1.mo, d1.delivery, d2.received
FROM
(SELECT month(deliveryDate) as mo, count(id) AS delivery
FROM ItemDelivery
WHERE year(deliveryDate)=2021 group by month(deliveryDate)) as d1,
(SELECT month(receiveDate) as mo, count(id) AS received
FROM ItemDelivery
WHERE year(receiveDate)=2021 group by month(receiveDate)) as d2
Output:
mo delivery received
1 2 1
2 3 1
3 1 1
1 2 1
2 3 1
3 1 1
1 2 1
2 3 1
3 1 1
1 2 1
2 3 1
3 1 1
This has also the same output except if I use condition d1.mo=d2.mo:
select d1.mo, d1.delivery, d2.received
from
(SELECT month(deliveryDate) as mo, count(id) as delivery
FROM ItemDelivery
WHERE year(deliveryDate)=2021 group by month(deliveryDate)) d1
inner join
(SELECT month(receiveDate) as mo, count(id) as received
FROM ItemDelivery
WHERE year(receiveDate)=2021 group by month(receiveDate)) d2
Any suggestions ?
SELECT
date_format(eventDate,'%b') AS mo,
SUM(delivery) AS delivery,
SUM(receive) AS receive
FROM
(
SELECT deliveryDate AS eventDate, 1 AS delivery, 0 AS receive FROM ItemDelivery
UNION ALL
SELECT receiveDate AS eventDate, 0 AS delivery, 1 AS receive FROM ItemDelivery
)
AS rotated
WHERE
eventDate >= '2021-01-01'
AND eventDate < '2022-01-01'
GROUP BY
month(eventDate)
If I have a table below:
company | year |quarter| revenue
A 2019 1 200
A 2019 3 100
B 2019 2 80
B 2019 4 40
How can I get the result displayed as:
year |quarter| company |revenue
2019 1 A
2019 2 A
2019 3 A
2019 4 A
2019 1 B
... ... B
A cross join should do
with cte as
(
select distinct company,year from t
)
select cte.year,s.qtr,cte.company
from cte
cross join (select 1 as qtr union select 2 union select 3 union select 4) s
order by cte.company,s.qtr;
I have a mysql table like this:
id course_id amount created_on
1 2 100 2018-01-03
2 1 300 2018-03-03
3 2 200 2018-01-03
4 4 400 2018-04-03
I would like to pass the course id and get total amount for that course donated for a year, based on month wise. If no donation is made for a month need to show it as 0
output as below:
month amount
1 300
2 0
3 200
4 400
5 0
6 0
7 0
8 0
9 0
10 0
11 0
12 0
You need a calendar month table for this, because there is no guarantee that your current table has data for every month.
SELECT
t1.month,
COALESCE(t2.amount, 0) AS amount
FROM
(
SELECT 1 AS month UNION ALL
SELECT 2 UNION ALL
SELECT 3 UNION ALL
SELECT 4 UNION ALL
SELECT 5 UNION ALL
SELECT 6 UNION ALL
SELECT 7 UNION ALL
SELECT 8 UNION ALL
SELECT 9 UNION ALL
SELECT 10 UNION ALL
SELECT 11 UNION ALL
SELECT 12
) t1
LEFT JOIN
(
SELECT MONTH(created_on) AS month, SUM(amount) AS amount
FROM yourTable
GROUP BY MONTH(created_on)
) t2
ON t1.month = t2.month
ORDER BY
t1.month;
I've 4 tables as shown below
doctors
id name
------------
1 Mathew
2 Praveen
3 Rosie
4 Arjun
5 Denis
doctors_appointments
id doctors_id patient_name contact date status
--------------------------------------------------------------------------------------
1 5 Nidhin 9876543210 2012-12-10 15:39:41 Registered
2 5 Sunny 9876543210 2012-12-18 15:39:48 Registered
3 5 Mani 9876543210 2012-12-12 15:39:57 Registered
4 2 John 9876543210 2012-12-24 15:40:09 Registered
5 4 Raj 9876543210 2012-12-05 15:41:57 Registered
6 3 Samuel 9876543210 2012-12-14 15:41:33 Registered
7 2 Louis 9876543210 2012-12-24 15:40:23 Registered
8 1 Federick 9876543210 2012-12-28 15:41:05 Registered
9 2 Sam 9876543210 2012-12-12 15:40:38 Registered
10 4 Sita 9876543210 2012-12-12 15:41:00 Registered
doctors_dutyplan
id doctor_id weeks time no_of_patients
------------------------------------------------------------------
1 1 3,6,7 9:00am-1:00pm 10
2 2 3,4,5 1:00pm-4:00pm 7
3 3 3,6,7 10:00am-2:00pm 10
4 4 3,4,5,6 8:30am-12:30pm 12
5 5 3,4,5,6,7 9:00am-4:00pm 30
emp_leave
id empid leavedate
--------------------------------
1 2 2012-12-05 14:42:36
2 2 2012-12-03 14:42:59
3 3 2012-12-03 14:43:06
4 3 2012-12-06 14:43:14
5 5 2012-12-04 14:43:24
My task is to find all the days in a month in which the doctor is available excluding the leave dates.
My query what is wrote is given below:
SELECT DATE_ADD( '2012-12-01', INTERVAL
ROW DAY ) AS Date,
ROW +1 AS DayOfMonth
FROM (
SELECT #row := #row +1 AS
ROW FROM (
SELECT 0
UNION ALL SELECT 1
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
UNION ALL SELECT 6
)t1, (
SELECT 0
UNION ALL SELECT 1
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
UNION ALL SELECT 6
)t2, (
SELECT #row := -1
)t3
LIMIT 31
)b
WHERE DATE_ADD( '2012-12-01', INTERVAL
ROW DAY )
BETWEEN '2012-12-01'
AND '2012-12-31'
AND DAYOFWEEK( DATE_ADD( '2012-12-01', INTERVAL
ROW DAY ) ) =2
AND DATE_ADD( '2012-12-01', INTERVAL
ROW DAY ) NOT
IN (
SELECT DATE_FORMAT( l.leavedate, '%Y-%m-%d' ) AS date
FROM doctors_dutyplan d
LEFT JOIN emp_leave AS l ON d.doctor_id = l.empid
WHERE doctor_id =2
)
This works fine for all doctors who took any leave in a particular day in a month (here in the example it is Decemeber 2012). and the result for the above query is shown below:
Date DayOfMonth
-----------------------
2012-12-10 10
2012-12-17 17
2012-12-24 24
2012-12-31 31
But on the other hand for the doctors who didn't took any leave , for that my query is showing empty table, example for the doctor Mathew whose id is 1, my query returns an empty result
can anyone please tell a solution for this problem.
Thanks in advance.
Your query is large, but this part looks fishy:
NOT IN (
SELECT DATE_FORMAT( l.leavedate, '%Y-%m-%d' ) AS date
FROM doctors_dutyplan d
LEFT JOIN emp_leave AS l ON d.doctor_id = l.empid
WHERE doctor_id =2
The left join means a null would be returned for doctor 1. Now, col1 not in (null) does not behave as you may expect. It translates to:
col1 <> null
Which is never true. You could solve this by changing the left join to an inner join, so an empty set instead of null is returned for a doctor without leave.
I have a table like this:
id employee_id contract_id month year d1 d2 d3
1 25 1 11 2011 1 01 01
2 16 5 11 2011 1 11 0
3 29 3 11 2011 1 001 100
1 25 4 11 2011 0 11 011
Suppose I need data for month='11' AND year='2011', then for all rows having the same 'employee_id', the data should merge like this:
id employee_id contract_id month year d1 d2 d3
1 25 1,4 11 2011 1,0 01,11 01,011
2 16 5 11 2011 1 11 0
3 29 3 11 2011 1 001 100
I was trying GROUP_CONCAT but couldn't figure out the query. Please help.
SELECT
id,
employee_id,
GROUP_CONCAT(contract_id SEPARATOR ',') AS contract_ids,
`month`,
`year`,
GROUP_CONCAT(d1 SEPARATOR ',') AS d1s,
GROUP_CONCAT(d2 SEPARATOR ',') AS d2s,
GROUP_CONCAT(d3 SEPARATOR ',') AS d3s
FROM
`table`
WHERE
`month` = 11 AND `year` = 2011
GROUP BY
employee_id
SELECT *,
GROUP_CONCAT(`d2`) as `d2`,
GROUP_CONCAT(`d3`) as `d3`,
GROUP_CONCAT(`contract_id`) as contract_id
FROM table WHERE month='11' AND year='2011' GROUP BY employee_id;