hi i am trying to solve this problem from 2 days please help. I have a table like below. i am trying to get crosstab display
expenditures
id name
1 exp1
2 exp2
3 exp3
4 exp4
5 exp5
stations
id name
1 station1
2 station2
3 station3
4 station4
expenses
expenditure_id station_id year month expense
1 1 2015 1 10
1 2 2015 1 20
1 3 2015 1 15
1 4 2015 1 10
1 1 2015 2 20
1 1 2015 3 30
1 1 2015 4 40
2 1 2015 1 20
2 1 2015 2 10
2 1 2015 3 20
I am trying get result like this
for year 2015
expenditure station1 station2 station3 station4
exp1 100 20 15 0
exp2 50 0 0 0
where value of station1 station2 will be the sum of month expense
This is the mysql query as your requirement, use Laravel query builder to run this query as raw query, if you donot know how to run raw query in laravel let me know, in the mean while run the query in phpmyadmin/mysql client and see whether its give you the desired output .
SELECT y.expenditure,
MAX(CASE y.station WHEN 'station1' THEN y.totalexpense END) 'station1',
MAX(CASE y.station WHEN 'station2' THEN y.totalexpense END) 'station2',
MAX(CASE y.station WHEN 'station3' THEN y.totalexpense END) 'station3',
MAX(CASE y.station WHEN 'station4' THEN y.totalexpense END) 'station4'
FROM (
SELECT exp.name AS expenditure,st.name AS station,x.totalexpense
FROM expenditures AS exp
LEFT JOIN
(SELECT expenditure_id,station_id,SUM(expense) as totalexpense
FROM expenses
WHERE year = '2015'
GROUP by expenditure_id,station_id
)
AS x ON exp.id = x.expenditure_id
LEFT JOIN stations AS st ON x.station_id = st.id
) AS y
GROUP BY y.expenditure
I assume you have only 4 stations, if stations are unknown numbers then you can use a prepared statement and create this dynamically:
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)
assume that there is a table like this:
sensor_id temperature device date
x01 18 d1 2018-07-01
x02 23 d1 2018-08-01
x01 21 d2 2018-07-01
x02 30 d2 2018-08-01
x01 28 d3 2018-07-01
x02 14 d3 2018-08-01
x01 11 d4 2018-08-01
x02 10 d4 2018-08-01
I need a result table like this:
below15 above15_below22 above22 month
0 2 1 7
3 0 2 8
actually, It groups data by months and counts which sensors are below 15 degrees, above 15 and below 22 degrees, ...
sorry I am not very familiar with MySQL because of my background education.
I write this code:
SELECT COUNT(*) as below15,MONTH(date) as month_num FROM `sensor_table` WHERE temperature<15 GROUP BY MONTH(date)
my problem is how can I generate the rest of the table.
use case when and aggregate funtion sum
select sum( case when temperature<15 then 1 else 0 end ) as
below15,
sum(case when temperature>15 and temperature<22 then 1 else 0 end) as
above15_below22,
sum(case when temperature>22 then 1 else 0 end) as above22 ,month(date)
as month from your_table
group by month
http://www.sqlfiddle.com/#!9/d4009a/3
we have two columns id and monthid.
The output what I'm looking for is to divide year from month Id based on quarter . The output column should be from quarter. If id is active output should be 1 else 0 .If id comes in any of the 1st quarter (eg:only 1) the output is still 1 .
Like this:
id month
-----------------------------------
100 2012-03-01 00:00:00.0
100 2015-09-01 00:00:00.0
100 2016-10-01 00:00:00.0
100 2015-11-01 00:00:00.0
100 2014-01-01 00:00:00.0
100 2013-04-01 00:00:00.0
100 2014-12-01 00:00:00.0
100 2015-02-01 00:00:00.0
100 2014-06-01 00:00:00.0
100 2013-01-01 00:00:00.0
100 2014-05-01 00:00:00.0
100 2016-05-01 00:00:00.0
100 2013-07-01 00:00:00.0
result should be something like
ID YEAR QTR output (1 or 0)
--------------------------------------------------
100 2012 1 1
100 2012 2 0
100 2012 3 0
100 2012 4 0
100 2013 1 1
100 2013 2 1
100 2013 3 1
100 2013 4 0
Below is the one I tried but it doesn't return the expected results. Please help me achieve this.I want when the ouput is 0 as well.
select a.id,a.year,a.month,
CASE WHEN a.month BETWEEN 1 AND 4 THEN 1
ELSE 0 END as output
from
(select id,trim(substring(claim_month_id,1,4)) as year,(INT((MONTH(monthid)-1)/3)+1) as month from test) a
group by a.id,a.year,a.month
Any help would be appreciated.
#Ani; there is no hierarchical query in Hive to create four quarters (1,2,3,4) so I create a small table for it. Then I get all patient_id, year and month that exists in ims_patient_activity_diagnosis table. Finally, I did a right join on all possible patient id, year and quarters (1,2,3,4); If the id or year or quarter does not exists in the right join, then there is no activity for that id, year and quarter. I assign activity=0 for those rows.
I also inserted patient id=200 to test if there are more patient id in the table. Hope this helps. Thanks.
create table dbo.qtrs(month int);
insert into qtrs values (1),(2),(3),(4);
select DISTINCT NVL(ims.id, qtr.id) as patient_id,
qtr.year as year,
qtr.month as month,
CASE WHEN ims.id > 0 THEN 1 ELSE 0 END as activity
from sandbox_grwi.ims_patient_activity_diagnosis ims
right join (select distinct ims.id,YEAR(ims.month_dt) as year,qtrs.month from sandbox_grwi.ims_patient_activity_diagnosis ims join dbo.qtrs qtrs) qtr
on (ims.id=qtr.id and YEAR(ims.month_dt)=qtr.year and INT((MONTH(month_dt)-1)/3)+1=qtr.month)
sort by patient_id, year, month;
Sample Result:
p_id year month activity
100 2012 1 1
100 2012 2 0
100 2012 3 0
100 2012 4 0
100 2013 1 1
100 2013 2 1
100 2013 3 1
100 2013 4 0
100 2014 1 1
100 2014 2 1
100 2014 3 0
100 2014 4 1
100 2015 1 1
100 2015 2 0
100 2015 3 1
100 2015 4 1
100 2016 1 0
100 2016 2 1
100 2016 3 0
100 2016 4 1
200 2012 1 1
200 2012 2 0
200 2012 3 0
200 2012 4 0
200 2013 1 0
200 2013 2 1
200 2013 3 0
200 2013 4 0
additional sample data:
insert into sandbox_grwi.ims_patient_activity_diagnosis values
(200, '2012-03-01'),
(200, '2013-04-01');
I am using Mysql and I want count distinct value and then make the distinct values as the column name.
I have a table Students like this
ID Names Age
1 Tim 12
2 James 14
3 White 13
4 John 13
5 Annie 11
6 Judy 13
I want to find how many people in each age. My expected result is:
11 12 13 14
1 1 3 1
I tried the query: "Select count(age), age from Students group by age;"
It gives out:
count(age) age
1 11
1 12
3 13
1 14
How can I take a "transpose" to the table?
If you are using MySQL you will need to know age in advance:
SELECT
SUM(CASE WHEN (age='11') THEN 1 ELSE 0 END) AS 11,
SUM(CASE WHEN (age='12') THEN 1 ELSE 0 END) AS 12,
SUM(CASE WHEN (age='13') THEN 1 ELSE 0 END) AS 13,
SUM(CASE WHEN (age='14') THEN 1 ELSE 0 END) AS 14
FROM
Students
My table votes contains votes that have been made by users at different times:
id item_id position user_id created_at
1 2 0 1 11/21/2013 11:27
26 1 1 1 11/21/2013 11:27
27 3 2 1 11/21/2013 11:27
42 2 2 1 12/7/2013 2:20
41 3 1 1 12/7/2013 2:20
40 1 0 1 12/7/2013 2:20
67 2 2 1 12/13/2013 1:13
68 1 1 1 12/13/2013 1:13
69 3 0 1 12/13/2013 1:13
84 2 0 1 12/28/2013 2:29
83 3 2 1 12/28/2013 2:29
82 1 1 1 12/28/2013 2:29
113 3 0 1 1/17/2014 22:08
114 1 1 1 1/17/2014 22:08
115 2 2 1 1/17/2014 22:08
138 2 0 1 1/20/2014 16:49
139 1 1 1 1/20/2014 16:49
140 3 2 1 1/20/2014 16:49
141 1 1 11 1/20/2014 16:51
142 3 2 11 1/20/2014 16:51
143 2 0 11 1/20/2014 16:51
I need to tally the results on a monthly basis but here's the tricky part: the start/end of the month does not necessarily fall on the first day of the month. So if the votes are due on the 10th day of every month, I need a vote that was cast on the 10th to be in a different group from a vote that was cast on the 11th. Using the data above, I want to get three groups:
Group 1: 6 votes (11/21 and 12/7)
Group 2: 6 votes (12/13, 12/28)
Group 3: 9 votes (1/17, 1/20)
I've tried a lot of approaches but to no avail. This is my query right now:
select created_at, ADDDATE(DATE_FORMAT(created_at, '%Y-%m-01'),interval 10 day) as duedate,count("id") from votes where list_id = 2 group by duedate
I am getting group sizes of 3, 9, and 9, not 6, 6 and 9. Any help you can provide would be much appreciated. Thanks.
Your query is close. You just need to subtract 9 days (10 - 1) from the current day to get the month:
select created_at, date_sub(created_at, interval 9 day) as duedate,
count(id)
from votes
where list_id = 2
group by duedate;
date_format() converts a date to a string. There is no need to convert a date value to a character value for this query.
EDIT:
To group by month:
select date_format(date_sub(created_at, interval 9 day), '%Y-%m') as YYYYMM,
count(id)
from votes
where list_id = 2
group by YYYYMM;