Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I have table given below
Year Month Pro Revenue
2019 | Jan | ABC | 1200
2019 | Feb | ABC | 2451
2019 | Mar | ABC | 6543
2019 | Apr | ABC | 3987
2019 | May | ABC | 4097
2019 | Jun | ABC | 4587
2019 | Jul | ABC | 3878
2019 | Aug | ABC | 1098
2019 | Sep | ABC | 3201
2019 | Oct | ABC | 1209
2019 | Nov | ABC | 4398
2019 | Dec | ABC | 4517
Can someone pls help me here, i am not able to create a sql query for the following
which quarter has the best revenue?
SELECT SUM(C.REVENUE)S_REVENUE,
CASE
WHEN C.MONTH IN('Jan','Feb','Mar') THEN 1
WHEN C.MONTH IN('Apr','May','Jun')THEN 2
WHEN C.MONTH IN('Jul','Aug','Sep')THEN 3
ELSE 4
END AS QUART
FROM YOUR_TABLE AS C
GROUP BY
CASE
WHEN C.MONTH IN('Jan','Feb','Mar') THEN 1
WHEN C.MONTH IN('Apr','May','Jun')THEN 2
WHEN C.MONTH IN('Jul','Aug','Sep')THEN 3
ELSE 4
END
Another option would be:
DECLARE #Revenue table ( [Year] int, [Month] varchar(3), Pro varchar(3), Revenue decimal(18,2) );
INSERT INTO #Revenue VALUES
( 2019, 'Jan', 'ABC', 1200 ),
( 2019, 'Feb', 'ABC', 2451 ),
( 2019, 'Mar', 'ABC', 6543 ),
( 2019, 'Apr', 'ABC', 3987 ),
( 2019, 'May', 'ABC', 4097 ),
( 2019, 'Jun', 'ABC', 4587 ),
( 2019, 'Jul', 'ABC', 3878 ),
( 2019, 'Aug', 'ABC', 1098 ),
( 2019, 'Sep', 'ABC', 3201 ),
( 2019, 'Oct', 'ABC', 1209 ),
( 2019, 'Nov', 'ABC', 4398 ),
( 2019, 'Dec', 'ABC', 4517 );
SELECT
Qtr,
SUM ( [Revenue] ) AS QtrRev
FROM #Revenue
CROSS APPLY (
SELECT DATEPART ( quarter, CAST (
CASE [Month]
WHEN 'Jan' THEN '1'
WHEN 'Feb' THEN '2'
WHEN 'Mar' THEN '3'
WHEN 'Apr' THEN '4'
WHEN 'May' THEN '5'
WHEN 'Jun' THEN '6'
WHEN 'Jul' THEN '7'
WHEN 'Aug' THEN '8'
WHEN 'Sep' THEN '9'
WHEN 'Oct' THEN '10'
WHEN 'Nov' THEN '11'
WHEN 'Dec' THEN '12'
END + '/01/' + CAST ( [Year] AS varchar(4) ) AS date ) ) AS Qtr
) AS Qtr
WHERE
[Year] = 2019
GROUP BY Qtr
ORDER BY
QtrRev DESC;
Which returns
+-----+----------+
| Qtr | QtrRev |
+-----+----------+
| 2 | 12671.00 |
| 1 | 10194.00 |
| 4 | 10124.00 |
| 3 | 8177.00 |
+-----+----------+
To get the top performing quarter:
SELECT TOP 1
Qtr,
SUM ( [Revenue] ) AS QtrRev
FROM #Revenue...
Returns
+-----+----------+
| Qtr | QtrRev |
+-----+----------+
| 2 | 12671.00 |
+-----+----------+
Ideally, you would add a Qtr column that stores the quarter the revenue belongs to, or at the very least change your Month column to a tinyint and store the numeric value over a string representation of the month.
Related
This question already has answers here:
How can I return pivot table output in MySQL?
(10 answers)
Closed 9 years ago.
i have problem with transposing row to column and column to row.
I can do that if it just transpose row to column or column to row.
This my table with data
UNIT|JAN|FEB|MAR|APR|MEI|JUN
CS-1|100|200|300|400|500|600
CS-2|111|222|333|444|555|666
CS-3|331|123|423|923|918|123
and I would like to get the following output
MONTH|CS-1|CS-2|CS-3
JAN |100 |111 |331
FEB |200 |222 |123
MAR |300 |333 |423
etc..
Anybody know how to do this? Thanks very much!
You can do it this way
SELECT month,
MAX(CASE WHEN unit = 'CS-1' THEN value END) `CS-1`,
MAX(CASE WHEN unit = 'CS-2' THEN value END) `CS-2`,
MAX(CASE WHEN unit = 'CS-3' THEN value END) `CS-3`
FROM
(
SELECT unit, month,
CASE month
WHEN 'JAN' THEN jan
WHEN 'FEB' THEN feb
WHEN 'MAR' THEN mar
WHEN 'APR' THEN apr
WHEN 'MAY' THEN may
WHEN 'JUN' THEN jun
END value
FROM table1 t CROSS JOIN
(
SELECT 'JAN' month UNION ALL
SELECT 'FEB' UNION ALL
SELECT 'MAR' UNION ALL
SELECT 'APR' UNION ALL
SELECT 'MAY' UNION ALL
SELECT 'JUN'
) c
) q
GROUP BY month
ORDER BY FIELD(month, 'JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN')
Output:
| MONTH | CS-1 | CS-2 | CS-3 |
|-------|------|------|------|
| JAN | 100 | 111 | 331 |
| FEB | 200 | 222 | 123 |
| MAR | 300 | 333 | 423 |
| APR | 400 | 444 | 923 |
| MAY | 500 | 555 | 918 |
| JUN | 600 | 666 | 123 |
Here is SQLFiddle demo
I have this table: "sales"
+-------------+---------+
| date | total |
+-------------+---------+
| 2018-12-04 | 269.10 |
| 2018-12-05 | 29.00 |
| 2018-12-06 | 107.10 |
| 2018-12-06 | 34.00 |
| 2018-12-08 | 69.50 |
| 2018-12-08 | 223.00 |
| 2018-12-08 | 68.00 |
| 2018-12-09 | 99.00 |
| 2018-12-10 | 59.50 |
| ... | ... |
+-------------+---------+
I'm trying this query
SELECT DAY(date) AS Days,
SUM(CASE WHEN MONTH(date) = 12 THEN total ELSE NULL END) AS December
FROM sales WHERE YEAR(date) = 2018 GROUP BY date
And I get
+-------+----------+
| Days | December |
+-------+----------+
| 4 | 269.10 |
| 5 | 29.00 |
| 6 | 141.10 |
| 8 | 360.50 |
| 9 | 99.00 |
| 10 | 59.50 |
| ... | ... |
+-------+----------+
But I want consecutive days like this:
+-------+----------+
| Days | December |
+-------+----------+
| 1 | NULL |
| 2 | NULL |
| 3 | NULL |
| 4 | 269.10 |
| 5 | 29.00 |
| 6 | 141.10 |
| 7 | NULL |
| 8 | 360.50 |
| 9 | 99.00 |
| 10 | 59.50 |
| ... | ... |
| 31 | 123.00 |
+-------+----------+
Can you help me plss..
PS: I have several months and years in "date" column from "sales" table.
This recursive CTE generates a list of dates corresponding to the month and year specified in the doi CTE, and then LEFT JOINs that to the sales table to get the sales for that month. It will work for any month/year, just change the values in the doi CTE, and the title of the SUM column (currently December) to suit.
WITH RECURSIVE doi AS (
SELECT 12 AS month,
2018 AS year
),
cte AS (
SELECT DATE(CONCAT_WS('-', year, month, 1)) AS date
FROM doi
UNION ALL
SELECT date + INTERVAL 1 DAY
FROM cte
WHERE date < LAST_DAY(date)
)
SELECT DAY(cte.date) AS Days,
ROUND(SUM(s.total),2) AS December
FROM cte
LEFT JOIN sales s ON s.date = cte.date
GROUP BY cte.date
ORDER BY cte.date
Output is too long to show here but can be seen at this demo on dbfiddle
Update
To expand this query to cover an entire year requires changing the approach slightly in terms of generating an entire year's worth of dates, and then using conditional aggregation to get the sums for each day of each month:
WITH RECURSIVE doi AS (
SELECT 2018 AS year
),
cte AS (
SELECT DATE(CONCAT_WS('-', year, 1, 1)) AS date
FROM doi
UNION ALL
SELECT date + INTERVAL 1 DAY
FROM cte
CROSS JOIN doi
WHERE date < DATE(CONCAT_WS('-', doi.year, 12, 31))
)
SELECT DAY(cte.date) AS Days,
ROUND(SUM(CASE WHEN MONTH(s.date) = 1 THEN s.total END),2) AS January,
ROUND(SUM(CASE WHEN MONTH(s.date) = 2 THEN s.total END),2) AS February,
ROUND(SUM(CASE WHEN MONTH(s.date) = 3 THEN s.total END),2) AS March,
ROUND(SUM(CASE WHEN MONTH(s.date) = 4 THEN s.total END),2) AS April,
ROUND(SUM(CASE WHEN MONTH(s.date) = 5 THEN s.total END),2) AS May,
ROUND(SUM(CASE WHEN MONTH(s.date) = 6 THEN s.total END),2) AS June,
ROUND(SUM(CASE WHEN MONTH(s.date) = 7 THEN s.total END),2) AS July,
ROUND(SUM(CASE WHEN MONTH(s.date) = 8 THEN s.total END),2) AS August,
ROUND(SUM(CASE WHEN MONTH(s.date) = 9 THEN s.total END),2) AS September,
ROUND(SUM(CASE WHEN MONTH(s.date) = 10 THEN s.total END),2) AS October,
ROUND(SUM(CASE WHEN MONTH(s.date) = 11 THEN s.total END),2) AS November,
ROUND(SUM(CASE WHEN MONTH(s.date) = 12 THEN s.total END),2) AS December
FROM cte
LEFT JOIN sales s ON s.date = cte.date
GROUP BY DAY(cte.date)
ORDER BY DAY(cte.date)
Demo on dbfiddle
generate your months using union and do right join
select t1.d as Days
, sum(iif(month(date) = 12, total, null) as December
from sales
right join (select 1 as d
union select 2 union select 3 union select 4 union select 5 union select 6
union select 7 union select 8 union select 9 union select 10 union select 11
.... ) as t1 on t1.d = day(date)
where year(date) = 2012
group by date
if you are using mysql v8.0, you can use recursive queries.
with recursive cte as(
select 1 as d
union all
select d + 1 from cte where d < day(last_day('2019-12-01'))
)
select coalesce(day(s.date), t1.d) as Days
, sum(iif(month(s.date) = 12, total, null) as December
from sales s
right join cte as t1 on t1.d = day(s.date)
where year(date) = 2012
group by coalesce(day(s.date), t1.d)
I had a problem. I have the data like below:
-----------------------
| last_login_dt |
-----------------------
| 2015-08-11 08:06:36 |
| 2015-06-10 22:06:43 |
| 2015-06-11 08:06:58 |
| 2015-09-11 08:06:45 |
-----------------------
So far, I managed to count this kind of data and turn into this using below statement:
SELECT DATE_FORMAT(last_login_dt,'%m/%Y') as `month`,
count(last_login_dt) as `total_visits` from public_user
WHERE DATE_FORMAT(last_login_dt,'%Y') = YEAR(CURDATE())
group by DATE_FORMAT(last_login_dt,'%m/%Y')
order by `month` asc;
----------------------------
| month | total_visits |
----------------------------
| 06/2015 | 2 |
| 08/2015 | 1 |
| 09/2015 | 1 |
----------------------------
The problem is, how to turn the result like below. Instead this table only have 4 rows of data, how to create a jan, feb, mar, apr ... row with total_visit = 0:
---------------------
| Month | Total |
---------------------
| Jan | 0 |
| Feb | 0 |
| Mar | 0 |
| Apr | 0 |
| May | 0 |
| Jun | 2 |
| Jul | 0 |
| Aug | 1 |
| Sep | 1 |
| Oct | 0 |
| Nov | 0 |
| Dis | 0 |
---------------------
I use your own query because it's working and I modified it a bit. Consider the query below:
SELECT `month`, `total_visits` FROM
(
SELECT * FROM
(
SELECT '01' AS `month_num`, 'Jan' As `month`, 0 AS `total_visits`
UNION
SELECT '02' AS `month_num`, 'Feb' AS `month`, 0 AS `total_visits`
UNION
SELECT '03' AS `month_num`, 'Mat' AS `month`, 0 AS `total_visits`
UNION
SELECT '04' AS `month_num`, 'Apr' AS `month`, 0 AS `total_visits`
UNION
SELECT '05' AS `month_num`, 'May' AS `month`, 0 AS `total_visits`
UNION
SELECT '06' AS `month_num`, 'Jun' AS `month`, 0 AS `total_visits`
UNION
SELECT '07' AS `month_num`, 'Jul' AS `month`, 0 AS `total_visits`
UNION
SELECT '08' AS `month_num`, 'Aug' AS `month`, 0 AS `total_visits`
UNION
SELECT '09' AS `month_num`, 'Sep' AS `month`, 0 AS `total_visits`
UNION
SELECT '10' AS `month_num`, 'Oct' AS `month`, 0 AS `total_visits`
UNION
SELECT '11' AS `month_num`, 'Nov' AS `month`, 0 AS `total_visits`
UNION
SELECT '12' AS `month_num`, 'Dec' AS `month`, 0 AS `total_visits`
UNION
SELECT DATE_FORMAT(last_login_dt,'%m') as `month_num`, DATE_FORMAT(last_login_dt,'%b') as `month`,
count(last_login_dt) as `total_visits` from public_user
WHERE DATE_FORMAT(last_login_dt,'%Y') = YEAR(CURDATE())
group by DATE_FORMAT(last_login_dt,'%m/%Y')
order by `total_visits` desc
) AS tmp
GROUP BY `month`
) AS total_visits
ORDER BY `month_num`;
It results in:
---------------------
| Month | Total |
---------------------
| Jan | 0 |
| Feb | 0 |
| Mar | 0 |
| Apr | 0 |
| May | 0 |
| Jun | 2 |
| Jul | 0 |
| Aug | 1 |
| Sep | 1 |
| Oct | 0 |
| Nov | 0 |
| Dis | 0 |
---------------------
I first created the table that displays the months and its total_visits (which is obviously 0). Then I unite your query to the derived table I created. I also added the month_num field for the sole purpose of sorting the data by month although it's not shown in the final result.
You're almost there. Try this %b in your date format string:
mysql> SELECT DATE_FORMAT(NOW(), '%b');
+--------------------------+
| DATE_FORMAT(NOW(), '%b') |
+--------------------------+
| Jun |
+--------------------------+
1 row in set (0.00 sec)
mysql>
The format for the month name is %b.
So I think you must change the %m to %b.
Try this sql if it works:
SELECT DATE_FORMAT(last_login_dt,'%b/%Y') as `month`,
count(last_login_dt) as `total_visits` from public_user
WHERE DATE_FORMAT(last_login_dt,'%Y') = YEAR(CURDATE())
group by DATE_FORMAT(last_login_dt,'%m/%Y')
order by `month` asc;
UPDATE AS OF 06/11/2015 11:57 AM GMT+8
We cannot display list of months in rows, but rather I used to make a derived column to display months and in total_visits on the row. I used case for the query to check if date is for the specific month.
SELECT
CASE WHEN DATE_FORMAT(last_login_dt,'%m') = '01' THEN count(last_login_dt) ELSE '0' END AS Jan,
CASE WHEN DATE_FORMAT(last_login_dt,'%m') = '02' THEN count(last_login_dt) ELSE '0' END AS Feb,
CASE WHEN DATE_FORMAT(last_login_dt,'%m') = '03' THEN count(last_login_dt) ELSE '0' END AS Mar,
CASE WHEN DATE_FORMAT(last_login_dt,'%m') = '04' THEN count(last_login_dt) ELSE '0' END AS Apr,
CASE WHEN DATE_FORMAT(last_login_dt,'%m') = '05' THEN count(last_login_dt) ELSE '0' END AS May,
CASE WHEN DATE_FORMAT(last_login_dt,'%m') = '06' THEN count(last_login_dt) ELSE '0' END AS Jun,
CASE WHEN DATE_FORMAT(last_login_dt,'%m') = '07' THEN count(last_login_dt) ELSE '0' END AS Jul,
CASE WHEN DATE_FORMAT(last_login_dt,'%m') = '08' THEN count(last_login_dt) ELSE '0' END AS Aug,
CASE WHEN DATE_FORMAT(last_login_dt,'%m') = '09' THEN count(last_login_dt) ELSE '0' END AS Sep,
CASE WHEN DATE_FORMAT(last_login_dt,'%m') = '10' THEN count(last_login_dt) ELSE '0' END AS Oct,
CASE WHEN DATE_FORMAT(last_login_dt,'%m') = '11' THEN count(last_login_dt) ELSE '0' END AS Nov,
CASE WHEN DATE_FORMAT(last_login_dt,'%m') = '12' THEN count(last_login_dt) ELSE '0' END AS `Dec`
FROM public_user;
The result will be:
------------------------------------------------------------------------
| Jan | Feb | Mar| Apr| May| Jun| Jul| Aug | Sep| Oct | Nov | Dec |
------------------------------------------------------------------------
| 0 | 0 | 0 | 0 | 0 | 2 | 0 | 1 | 1 | 0 | 0 | 0 |
------------------------------------------------------------------------
This question already has answers here:
How can I return pivot table output in MySQL?
(10 answers)
Closed 9 years ago.
i have problem with transposing row to column and column to row.
I can do that if it just transpose row to column or column to row.
This my table with data
UNIT|JAN|FEB|MAR|APR|MEI|JUN
CS-1|100|200|300|400|500|600
CS-2|111|222|333|444|555|666
CS-3|331|123|423|923|918|123
and I would like to get the following output
MONTH|CS-1|CS-2|CS-3
JAN |100 |111 |331
FEB |200 |222 |123
MAR |300 |333 |423
etc..
Anybody know how to do this? Thanks very much!
You can do it this way
SELECT month,
MAX(CASE WHEN unit = 'CS-1' THEN value END) `CS-1`,
MAX(CASE WHEN unit = 'CS-2' THEN value END) `CS-2`,
MAX(CASE WHEN unit = 'CS-3' THEN value END) `CS-3`
FROM
(
SELECT unit, month,
CASE month
WHEN 'JAN' THEN jan
WHEN 'FEB' THEN feb
WHEN 'MAR' THEN mar
WHEN 'APR' THEN apr
WHEN 'MAY' THEN may
WHEN 'JUN' THEN jun
END value
FROM table1 t CROSS JOIN
(
SELECT 'JAN' month UNION ALL
SELECT 'FEB' UNION ALL
SELECT 'MAR' UNION ALL
SELECT 'APR' UNION ALL
SELECT 'MAY' UNION ALL
SELECT 'JUN'
) c
) q
GROUP BY month
ORDER BY FIELD(month, 'JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN')
Output:
| MONTH | CS-1 | CS-2 | CS-3 |
|-------|------|------|------|
| JAN | 100 | 111 | 331 |
| FEB | 200 | 222 | 123 |
| MAR | 300 | 333 | 423 |
| APR | 400 | 444 | 923 |
| MAY | 500 | 555 | 918 |
| JUN | 600 | 666 | 123 |
Here is SQLFiddle demo
I Have query result like this , Select Type,Jan,FEB From TableName :
+-----------+------+------+
| Type | JAN | FEB |
+-----------+------+------+
| MATIC | 137 | 128 |
| MOPED | 41 | 23 |
| MOPED PRM | 8 | 9 |
| SPORT | 55 | 62 |
+-----------+------+------+
4 rows in set (1.23 sec)
I want to add up the columns jan and columns feb, be like this
+-----------+------+------+------+
| Type | JAN | FEB | TOT |
+-----------+------+------+------+
| MATIC | 137 | 128 | 165 |
| MOPED | 41 | 23 | 64 |
| MOPED PRM | 8 | 9 | 17 |
| SPORT | 55 | 62 | 117 |
+-----------+------+------+------+
4 rows in set (1.23 sec)
is there a command such as
select type, jan, feb, sum (jan) + sum (feb) As TOT
From Table Name
This is my syntax
Select SubTbl2.jenis,
sum(If(Month = 1 and Year = 2013 ,Result,0)) as 'JAN',
sum(If(Month = 2 and Year = 2013,Result,0)) as 'FEB'
From (
select SubTbl1.jenis,month(SubTbl1.TglAmb) as Month,
year(SubTbl1.tglAmb) as Year,
count(SubTbl1.jenis) as Result
From (
select jual_leasing.TglAmb,jual_leasing.NoMsn,typemotor.jenis
,lokasi.lokasi3s
from jual_leasing
left join typeconvert
on jual_leasing.typeK = typeconvert.typesystem
left join typemotor
on typeconvert.typeconv = typemotor.type
left join lokasi
on jual_leasing.kodelok = lokasi.kodelokasi
where
lokasi.lokasi3S = 'YMS PURWODADI 3S'
group by jual_leasing.NoMsn)
as SubTbl1
group by SubTbl1.jenis,Month,Year )
as SubTbl2 group by SubTbl2.jenis;
The result is on Top , i try to add script on line 4 , with
JAN + FEB as TOT
but there is stil warning :
ERROR 1054 (42S22): Unknown column 'JAN' in 'field list'
Tq For advanced
To obtain tour desired output, simply do:
select type, jan, feb, jan + feb As TOT
from TableName
You do not need SUM, that is designed to add the values of different rows.
edit For your actual query, yes you can add two sums. Also, the following should work for you:
sum(If((Month = 1 or Month = 2) and Year = 2013 ,Result,0)) as 'TOT',
The MySQL documentation on arithmetic functions indicates that + is indeed the addition operator.
So, your query would be:
select type, jan, feb, jan + feb from table
Sum works over columns and not rows; you'd use this if you wanted the sum of both columns added together.
P.S. 137 + 128 = 265
I think you will find this question is getting down-voted because it is not really about programming - this is more of a general SQL syntax question. That being said, I think you should just be able to sum your values:
select type, jan, feb, jan + feb As TOT From Table Name
Just change the beginning of your query with this :
Select SubTbl2.jenis,
sum(If(Month = 1 and Year = 2013 ,Result,0)) as 'JAN',
sum(If(Month = 2 and Year = 2013,Result,0)) as 'FEB',
sum(If(Month = 1 and Year = 2013 ,Result,0)) +
sum(If(Month = 2 and Year = 2013,Result,0)) as 'TOT'
From (
Or
Select SubTbl2.jenis,
sum(If(Month = 1 and Year = 2013 ,Result,0)) as 'JAN',
sum(If(Month = 2 and Year = 2013,Result,0)) as 'FEB',
sum(If((Month = 1 or Month = 2) and Year = 2013,Result,0)) as 'TOT'
From (