Mysql group rows by date into 4 seasons + year - mysql

At the moment I am grouping the news into month+year but we dont have enough news articles. So instead would like to group them by season: summer, spring, autumn or winter + year
So instead of:
January 2013
March 2013
April 2013
It would be:
Summer 2013
Spring 2013
Monthly archieve
SELECT MONTHNAME(news_date) AS MONTH,
YEAR(news_date) AS YEAR,
COUNT(news_id) AS COUNT
FROM news
WHERE news_type = 'NEWS'
AND news_status = 'ENABLED'
GROUP BY CONCAT(MONTH(news_date), ' ', YEAR(news_date))
ORDER BY news_date DESC

SELECT CASE WHEN MONTH(news_date) IN (12, 1, 2) THEN 'Winter'
WHEN MONTH(news_date) IN (3, 4, 5) THEN 'Spring'
WHEN MONTH(news_date) IN (6, 7, 8) THEN 'Summer'
ELSE 'Fall' END AS Season,
YEAR(news_date) AS YEAR,
COUNT(news_id) AS COUNT
FROM news
WHERE news_type = 'NEWS'
AND news_status = 'ENABLED'
GROUP BY YEAR(news_date), Season
ORDER BY news_date DESC

To get numeric seasons (Winter as 0 through to Autumn as 3), try the more compact:
SELECT quantity, FLOOR((MONTH(date_field) % 12)/3) as season
FROM `tbl`
GROUP BY season

SELECT case when MONTH(news_date) between 3 and 5 then 'Spring',
when MONTH(news_date) between 6 and 8 then 'Summer',
when MONTH(news_date) between 9 and 11 then 'Autum',
when MONTH(news_date) >= 12 and MONTH(news_date) <= 2 then 'Winter'
end AS Period,
YEAR(news_date) AS YEAR,
COUNT(news_id) AS COUNT
FROM news
WHERE news_type = 'NEWS' AND news_status = 'ENABLED'
GROUP BY YEAR(news_date), Period
ORDER BY news_date DESC

use CASE statement like below in your query
CASE WHEN MONTH(news_date) = 1 or MONTH(news_date) = 2 or MONTH(news_date) = 3
THEN CONCAT('SPRING ' , YEAR(news_date) )
WHEN MONTH(news_date) = 4 or MONTH(news_date) = 5 or MONTH(news_date) = 6
THEN CONCAT('SUMMER ' , YEAR(news_date) )
WHEN MONTH(news_date) = 7 or MONTH(news_date) = 8 or MONTH(news_date) = 9
THEN CONCAT('AUTUMN ' , YEAR(news_date) )
WHEN MONTH(news_date) = 10 or MONTH(news_date) = 11 or MONTH(news_date) = 12
THEN CONCAT('WINTER ' , YEAR(news_date) )

Related

Cross tabulate data of products sold broken down by revenue and by product sold

Issues in getting the right frequency for the cross tabulated data. My expected output is something like this:
I tried replacing the COUNT statement with SUM statement
SUM(IF(product.product_id = 1, line_item.quantity, 0)) AS Soda,
SUM(IF(product.product_id = 2, line_item.quantity, 0)) AS Liquor,
SUM(IF(product.product_id = 3, line_item.quantity, 0)) AS Lemon,
SUM(IF(product.product_id = 4, line_item.quantity, 0)) AS Mango,
SUM(IF(product.product_id = 5, line_item.quantity, 0)) AS Inhaler,
SUM(1) AS Count
FROM line_item
JOIN product USING (product_id)
JOIN ( SELECT 0 lo, 500 hi UNION
SELECT 501 , 1000 UNION
SELECT 1001 , 1500 UNION
SELECT 1501 , 2000 UNION
SELECT 2001 , 2500 ) ranges ON (product.price * line_item.quantity) BETWEEN ranges.lo AND ranges.hi
GROUP BY ranges.lo, ranges.hi```
It is getting closer because it is distributing already the values in its ranges just that the values are not correct. I am expecting to see something like this:
[Expected Result][1]
[1]: https://i.stack.imgur.com/YuB92.png
After reviewing my code here is the answer:
SUM(product.product_id = 1) AS Soda,
SUM(product.product_id = 2) AS Liquor,
SUM(product.product_id = 3) AS Lemon,
SUM(product.product_id = 4) AS Mango,
SUM(product.product_id = 5) AS Inhaler,
SUM(1) AS Count
FROM line_item
JOIN product USING (product_id)
JOIN ( SELECT 0 lo, 500 hi UNION
SELECT 501 , 1000 UNION
SELECT 1001 , 1500 UNION
SELECT 1501 , 2000 UNION
SELECT 2001 , 2500 ) ranges ON product.price * line_item.quantity BETWEEN ranges.lo AND ranges.hi
GROUP BY ranges.lo, ranges.hi

write MySQL searching for more than one value in a column

SELECT
ID,
Division,
EffectiveDate,
PM,
case Status
when 0 then 'Dead'
when 1 then 'Active'
when 2 then 'Job'
when 3 then 'Pending'
when 4 then 'Sales Lead'
when 5 then 'Budget'
when 6 then 'Change Order'
end as Status,
Name,
Address,
ProjectType
FROM intranet.t_bidinfo
WHERE Division = 'TI'
AND EffectiveDate >= '2015-06-01'
AND Status = 6
ORDER BY EffectiveDate ASC
;
i need to return all the values with a status of 6 OR 2
i tried writing AND Status = 6 or 2 but that doesnt work =/
is this accomplished by joining tables or is there a simpler way?
thanks
SELECT
ID,
Division,
EffectiveDate,
PM,
case Status
when 0 then 'Dead'
when 1 then 'Active'
when 2 then 'Job'
when 3 then 'Pending'
when 4 then 'Sales Lead'
when 5 then 'Budget'
when 6 then 'Change Order'
end as Status,
Name,
Address,
ProjectType
FROM intranet.t_bidinfo
WHERE Division = 'TI'
AND EffectiveDate >= '2015-06-01'
AND ( Status = 6 OR Status = 2 )
ORDER BY EffectiveDate ASC
You were close, you just need a OR statement with Status = 2.
SELECT
ID,
Division,
EffectiveDate,
PM,
case Status
when 0 then 'Dead'
when 1 then 'Active'
when 2 then 'Job'
when 3 then 'Pending'
when 4 then 'Sales Lead'
when 5 then 'Budget'
when 6 then 'Change Order'
end as Status,
Name,
Address,
ProjectType
FROM intranet.t_bidinfo
WHERE Division = 'TI'
AND EffectiveDate >= '2015-06-01'
AND (Status = 2 OR Status = 6)
ORDER BY EffectiveDate ASC
;
Here is some more info.
You want either IN or OR -
AND Status IN (6, 2)
AND Status = 6 OR Status = 2
You can use IN in your query. Tyr this :
SELECT
ID,
Division,
EffectiveDate,
PM,
case Status
when 0 then 'Dead'
when 1 then 'Active'
when 2 then 'Job'
when 3 then 'Pending'
when 4 then 'Sales Lead'
when 5 then 'Budget'
when 6 then 'Change Order'
end as Status,
Name,
Address,
ProjectType
FROM intranet.t_bidinfo
WHERE Division = 'TI'
AND EffectiveDate >= '2015-06-01'
AND Status IN (6,2)
ORDER BY EffectiveDate ASC

Why MySQL full outer join returns nulls?

Why MySQL full outer join returns nulls?
Hi
I have the following data:
s_id,date,p_id,amount_sold
1, '2015-10-01', 1, 10
2, '2015-10-01', 2, 12
7, '2015-10-01', 1, 11
3, '2015-10-02', 1, 11
4, '2015-10-02', 2, 10
5, '2015-10-15', 1, 22
6, '2015-10-16', 2, 20
8, '2015-10-22', 3, 444
and i want my query to output something like this: (A = sum of amount_sold for p_id=1 for that date,B = sum of amount_sold for p_id=2 for that date)
date,A,B,Difference
'2015-10-01',21,12,9
'2015-10-02',11,10,1
'2015-10-15',22,0,22
'2015-10-01',0,20,-20
I tried with this query, but the order its returning is having NULLS and the output is wrong:
SELECT A.p_id,A.date,sum(A.amount_sold) A,B.Bs, (sum(A.amount_sold) - B.Bs) as difference FROM sales as A
LEFT JOIN (
SELECT SUM( amount_sold ) Bs,p_id,s_id, DATE
FROM sales
WHERE p_id =2
group by date
) as B ON A.s_id = B.s_id
where A.p_id=1 or B.p_id=2
group by A.date, A.p_id
UNION
SELECT A.p_id,A.date,sum(A.amount_sold) A,B.Bs, (sum(A.amount_sold) - B.Bs) as difference FROM sales as A
RIGHT JOIN (
SELECT SUM( amount_sold ) Bs,p_id,s_id, DATE
FROM sales
WHERE p_id =2
group by date
) as B ON A.s_id = B.s_id
where B.p_id=2
group by A.date, A.p_id
It returned:
p_id date A Bs difference
1 2015-10-01 21 NULL NULL
2 2015-10-01 12 12 0
1 2015-10-02 11 NULL NULL
2 2015-10-02 10 10 0
1 2015-10-15 22 NULL NULL
2 2015-10-16 20 20 0
What am i doing wrong here? and what is the correct way of doing it? any help would be appreciated.
A full join isn't needed. You can use conditional aggregation instead:
select
date,
sum(case when p_id = 1 then amount_sold else 0 end) a,
sum(case when p_id = 2 then amount_sold else 0 end) b,
sum(case when p_id = 1 then amount_sold else 0 end)
- sum(case when p_id = 2 then amount_sold else 0 end) difference
from sales
where p_id in (1,2)
group by date

Mysql case not working

SELECT
SQL_CALC_FOUND_ROWS a.* ,
zn.`name` AS zone_name,
c.`name` AS carrier_name,
CASE type
WHEN type=1 THEN 'General day'
ELSE 'Special date' END AS type_changed,
CASE week_day
WHEN week_day = -1 THEN 'notset'
WHEN week_day = 1 THEN 'monday'
WHEN week_day = 2 THEN 'tuesday'
WHEN week_day = 3 THEN 'wednesday'
WHEN week_day = 4 THEN 'thursday'
WHEN week_day = 5 THEN 'friday'
WHEN week_day = 6 THEN 'saturday'
WHEN week_day = 7 THEN 'sunday' END AS week_day_mod ,
IF(date = '0001-01-01 00:00:0', '--', DATE(date)) AS date_mod, IF(is_working_day = 1 ,'working day', 'day off') AS is_working_day_mod
FROM `ps_deliverytime_table` a
LEFT JOIN ps_zone AS zn ON(a.`id_zone` = zn.`id_zone`)
LEFT JOIN ps_carrier AS c ON(a.`id_carrier` = c.`id_carrier`)
WHERE 1 ORDER BY a.`id_time_table` ASC LIMIT 0,50
When week day is equal 1 it works fine but in other case it do not working
When you put column name after CASE, you shouldn't use WHEN column = value, just use WHEN value, because it automatically compares the column to each value in the WHEN clauses.
CASE type
WHEN 1 THEN 'General day'
ELSE 'Special date'
END AS type_changed,
CASE week_day
WHEN -1 THEN 'notset'
WHEN 1 THEN 'monday'
WHEN 2 THEN 'tuesday'
WHEN 3 THEN 'wednesday'
WHEN 4 THEN 'thursday'
WHEN 5 THEN 'friday'
WHEN 6 THEN 'saturday'
WHEN 7 THEN 'sunday'
END AS week_day_mod ,
When you do both, you're testing week_day = (week_day = -1), week_day = (week_day = 1), etc. It works on Monday because 1 = (1 = 1) is equivalent to 1 = 1, which is true; but on Tuesday, it's 2 = (2 = 2), which is equivalent to 2 = 1, which is false.

Subtract all the rows from the value of first row in a MySQL column

This is my Select query
Select
snpc_stats.gamedetail.Player,
Sum(snpc_stats.gamedetail.Points + snpc_stats.gamedetail.Hits) As TotalPoints,
COUNT(*) As 'Games Played',
Sum(If(snpc_stats.gamedetail.Finish = 1, 1, 0)) As Wins,
Sum(If(snpc_stats.gamedetail.Finish = 2, 1, 0)) As Second,
Sum(If(snpc_stats.gamedetail.Finish = 3, 1, 0)) As Third,
Round(Avg(snpc_stats.gamedetail.Finish),2) As 'Average Finish',
Sum(snpc_stats.gamedetail.Hits) As `Total Hits`,
Sum(snpc_stats.gamedetail.ChampFund) As ChampFund,
Sum(snpc_stats.games.BuyIn) + (snpc_stats.gamedetail.ChampFund) As Cost,
Sum(snpc_stats.gamedetail.Winnings) As Winnings,
Sum(snpc_stats.gamedetail.Winnings) - (snpc_stats.games.BuyIn) - (snpc_stats.gamedetail.ChampFund) As 'Total Winnings',
COUNT(snpc_stats.games.Round) As round
From
snpc_stats.gamedetail Inner Join
snpc_stats.games On snpc_stats.games.GameID =
snpc_stats.gamedetail.GamesID
Where
snpc_stats.games.Season = '2015 Season'
Group By
snpc_stats.gamedetail.Player, snpc_stats.games.Season
Order By
TotalPoints Desc
After the TotalPoints Column I like to add a column that show the amount of points each player trails behind the leader, like the table below:
Rank | Player | Total Points | Points Behind
1 Bill 164 -
2 Al 152 -12
3 Ed 151 -13
4 Jill 123 -41
5 Bob 121 -43
6 Joe 102 -62
7 Dave 82 -82
8 Rob 60 -104
9 Doug 60 -104
10 Don 51 -113
11 Dan 30 -134
Any help would be so appreciated!
solution (1)If you are using a server side language that connects to the database and runs the query, you can preserve total points value of first row in some variable and subtracting all the following rows from it
solution (2)make a sub query that returns total points of the first row and use it in the selection part of the query
Select
snpc_stats.gamedetail.Player,
Sum(snpc_stats.gamedetail.Points + snpc_stats.gamedetail.Hits) As TotalPoints,
(Sum(snpc_stats.gamedetail.Points + snpc_stats.gamedetail.Hits) - (Select Sum(snpc_stats.gamedetail.Points + snpc_stats.gamedetail.Hits) From snpc_stats.gamedetail Inner Join snpc_stats.games On snpc_stats.games.GameID = snpc_stats.gamedetail.GamesID Where snpc_stats.games.Season = '2015 Season' Group By snpc_stats.gamedetail.Player, snpc_stats.games.Seaso Order By Sum(snpc_stats.gamedetail.Points + snpc_stats.gamedetail.Hits) Desc Limit 1)) As Points Behind,
COUNT(*) As 'Games Played',
Sum(If(snpc_stats.gamedetail.Finish = 1, 1, 0)) As Wins,
Sum(If(snpc_stats.gamedetail.Finish = 2, 1, 0)) As Second,
Sum(If(snpc_stats.gamedetail.Finish = 3, 1, 0)) As Third,
Round(Avg(snpc_stats.gamedetail.Finish),2) As 'Average Finish',
Sum(snpc_stats.gamedetail.Hits) As `Total Hits`,
Sum(snpc_stats.gamedetail.ChampFund) As ChampFund,
Sum(snpc_stats.games.BuyIn) + (snpc_stats.gamedetail.ChampFund) As Cost,
Sum(snpc_stats.gamedetail.Winnings) As Winnings,
Sum(snpc_stats.gamedetail.Winnings) - (snpc_stats.games.BuyIn) - (snpc_stats.gamedetail.ChampFund) As 'Total Winnings',
COUNT(snpc_stats.games.Round) As round
From
snpc_stats.gamedetail Inner Join
snpc_stats.games On snpc_stats.games.GameID =
snpc_stats.gamedetail.GamesID
Where
snpc_stats.games.Season = '2015 Season'
Group By
snpc_stats.gamedetail.Player, snpc_stats.games.Season
Order By
TotalPoints Desc