Split and Switch function for ssrs 2014 - reporting-services

I am trying to get values of Q1, Q2 as per below expression in SSRS 2014 but i get an Error#. Can someone tell me what i am doing wrong.
Q1, Q2
=Split(
"Q" &
Switch(Month(Parameters!cEndDate.Value)<=3,1,
Month(Parameters!cEndDate.Value)<=6,2,
Month(Parameters!cEndDate.Value)<=9,3,
Month(Parameters!cEndDate.Value)<=12,4
)
& "," &
"Q" &
Switch(Month(Parameters!cEndDate.Value)<=3,1,
Month(Parameters!cEndDate.Value)<=6,2,
Month(Parameters!cEndDate.Value)<=9,3,
Month(Parameters!cEndDate.Value)<=12,4
)
,",")

Try:
=SWITCH(
Month(Parameters!cEndDate.Value) >= 1 and Month(Parameters!cEndDate.Value) <= 3 , "Q1",
Month(Parameters!cEndDate.Value) >= 4 and Month(Parameters!cEndDate.Value) <= 6 , "Q2",
Month(Parameters!cEndDate.Value) >= 7 and Month(Parameters!cEndDate.Value) <= 9 , "Q3",
Month(Parameters!cEndDate.Value) >= 10 and Month(Parameters!cEndDate.Value) <= 12 , "Q4"
)

Related

ANSI SQL grouping by (Indian) financial year YTD - (last 5 years YTD)

Can anyone kindly point out how to group data until today (for last 5 years) for Indian fiscal (Apr-Mar). Say for example I need to extract 'field1','field2' from table 'aaa' from 01-Apr to today date for the last 5 years. My current solution can work safe until Dec, but later will run into error
SELECT
"Date",
"Daily data",
"ID",
"GA%",
"MA%"
FROM "table"
WHERE month("Date") >= 4
AND month("Date") <= month(today())
AND date("Date") < date(today())
Expected result format grouped by fiscal years:
FY-1 sum(daily data during the period) sum(GA) sum(MA)
FY-2 sum(daily data during the period) sum(GA) sum(MA)
SELECT
"Date",
"Daily data",
"ID",
"GA%",
"MA%"
FROM "table"
WHERE
"Date" between '2021-04-01' and '2021-11-29'
OR
"Date" between '2020-04-01' and '2020-11-29'
OR
"Date" between '2019-04-01' and '2019-11-29'
OR
"Date" between '2018-04-01' and '2018-11-29'
OR
"Date" between '2017-04-01' and '2017-11-29'
untested notepad scribble
SELECT
MIN(`Date`) AS StartDate
, MAX(`Date`) AS EndDate
, COUNT(ID) AS CountId
, SUM(`GA%`) AS `TotalGa%`
, SUM(`MA%`) AS `TotalMa%`
FROM `table` AS aaa
WHERE
(
(YEAR(`Date`) BETWEEN YEAR(CURRENT_DATE) - 4 AND YEAR(CURRENT_DATE) - 1)
OR
(YEAR(`Date`) = YEAR(CURRENT_DATE) AND MONTH(`Date`) <= 11)
OR
(YEAR(`Date`) = YEAR(CURRENT_DATE) - 5 AND MONTH(`Date`) > 3)
)
AND
(
MONTH(`Date`) NOT IN (12, 1, 2, 3)
OR
YEAR(`Date`) = YEAR(CURRENT_DATE)
)
GROUP BY CASE WHEN MONTH(`Date`) <= 3 THEN YEAR(`Date`) - 1
ELSE YEAR(`Date`) END
ORDER BY MIN(`Date`) DESC

Using sum function with when case

SELECT '2017-05-30' AS `short_date`,
'Stats' AS `group`,
'Active ' AS `subgroup`,
'' AS `row`,
CASE
WHEN COUNT(DISTINCT(guild_name)) >= 1 AND COUNT(DISTINCT(guild_name)) <= 5 THEN '1 - 5 '
WHEN COUNT(DISTINCT(guild_name)) >= 6 AND COUNT(DISTINCT(guild_name)) <= 10 THEN '6 - 10 '
WHEN COUNT(DISTINCT(guild_name)) >= 11 AND COUNT(DISTINCT(guild_name)) <= 15 THEN '11 - 15 '
WHEN COUNT(DISTINCT(guild_name)) >= 16 AND COUNT(DISTINCT(guild_name)) <= 20 THEN '16 - 20 '
WHEN COUNT(DISTINCT(guild_name)) >= 21 AND COUNT(DISTINCT(guild_name)) <= 25 THEN '21 - 25 '
WHEN COUNT(DISTINCT(guild_name)) >= 30 THEN '> 30' END AS `value`
FROM table
WHERE guild_name !=0
GROUP BY
`short_date`,
`group`,
`subgroup`
How not to count a value in each case, how to count it once and use in each case?
How about you move the count to a subquery and move the case outside like this:
select `short_date`, `group`, `subgroup`, `row`,
CASE
WHEN nb_guild >= 1 AND nb_guild <= 5 THEN '1 - 5 '
WHEN nb_guild >= 6 AND nb_guild <= 10 THEN '6 - 10 '
WHEN nb_guild >= 11 AND nb_guild <= 15 THEN '11 - 15 '
WHEN nb_guild >= 16 AND nb_guild <= 20 THEN '16 - 20 '
WHEN nb_guild >= 21 AND nb_guild <= 25 THEN '21 - 25 '
WHEN nb_guild >= 30 THEN '> 30'
END AS `value`
from
(
SELECT '2017-05-30' AS `short_date`,
'Stats' AS `group`,
'Active ' AS `subgroup`,
'' AS `row`,
COUNT(DISTINCT(guild_name)) as nb_guild
FROM table
WHERE guild_name !=0
GROUP BY
`short_date`,
`group`,
`subgroup`
) as subquery
This way your count only gets executed once in the subquery and your outer query does its treatment on the resulting resultset.

Get specific data from 2 date for a timerange

The data is stored in DB in UTC , I have to convert local to UTC fetch it then show result in local time .
Now I am from India so if I want to search the data for today I have to query from 22nd March 6:30 PM UTC to 23rd March 6:30 PM UTC . Now Say I want to check data for every day of week until now which is 4:30 PM local . Now I wrote this query [ In simple words my objective is to get visitor number of each day from 12 AM to 4:30 PM ]
SELECT
FLOOR(TIMESTAMPDIFF(HOUR, "2017-03-16 18:29:59",
visit.date_created)/24) as dayofweek,
DAYOFWEEK(visit.date_created) day_num,
#rownum := #rownum + 1 as date_created_set_av,
count(distinct(visit.pkey)) AS Visits,
sum(revenue) AS Revenue,
sum(revenue) / count(distinct(visit.pkey)) as EPC
FROM la_20.visit, la_20.action
cross join (select #rownum := 0) r
WHERE visit.pkey=action.pkey and (visit.is_bot = 0)
AND visit.date_created >="2017-03-16 18:29:59"
AND visit.date_created <="2017-03-23 18:29:59"
AND TIME(visit.date_created)<="16:30:00"
GROUP BY dayofweek order by day_num
but what it does is fetch the value from 2017-03-23 00:00:00 to 2017-03-23 16:30:00 . What I need is to show result of 16th to 23rd everyday's data from 18:29:59 to 16:30:00. Remember I need the result of everyday's not one day's. Can anyone help
You should change your WHERE clause into
WHERE visit.pkey=action.pkey and (visit.is_bot = 0)
AND visit.date_created >="2017-03-22 18:29:59" and visit.date_created <="2017-03-23 14:29:59"
UPDATED
Today midnight: DATEADD(d,0,DATEDIFF(d,0,GETDATE()))
Today 4pm: DATEADD(HOUR, 16, DATEADD(d,0,DATEDIFF(d,0,GETDATE())))
WHERE visit.pkey=action.pkey and (visit.is_bot = 0)
AND visit.date_created >= DATEADD(d,0,DATEDIFF(d,0,GETDATE())) and visit.date_created <= DATEADD(HOUR, 16, DATEADD(d,0,DATEDIFF(d,0,GETDATE())))
Update 2:
Then you'll have to expand your where clause like this I guess.
WHERE visit.pkey=action.pkey and (visit.is_bot = 0)
AND (
(visit.date_created >= DATEADD(d, 0,DATEDIFF(d,0,GETDATE())) and visit.date_created <= DATEADD(HOUR, 16, DATEADD(d, 0,DATEDIFF(d,0,GETDATE()))))
OR (visit.date_created >= DATEADD(d,-1,DATEDIFF(d,0,GETDATE())) and visit.date_created <= DATEADD(HOUR, 16, DATEADD(d,-1,DATEDIFF(d,0,GETDATE()))))
OR (visit.date_created >= DATEADD(d,-2,DATEDIFF(d,0,GETDATE())) and visit.date_created <= DATEADD(HOUR, 16, DATEADD(d,-2,DATEDIFF(d,0,GETDATE()))))
OR (visit.date_created >= DATEADD(d,-3,DATEDIFF(d,0,GETDATE())) and visit.date_created <= DATEADD(HOUR, 16, DATEADD(d,-3,DATEDIFF(d,0,GETDATE()))))
OR (visit.date_created >= DATEADD(d,-4,DATEDIFF(d,0,GETDATE())) and visit.date_created <= DATEADD(HOUR, 16, DATEADD(d,-4,DATEDIFF(d,0,GETDATE()))))
OR (visit.date_created >= DATEADD(d,-5,DATEDIFF(d,0,GETDATE())) and visit.date_created <= DATEADD(HOUR, 16, DATEADD(d,-5,DATEDIFF(d,0,GETDATE()))))
OR (visit.date_created >= DATEADD(d,-6,DATEDIFF(d,0,GETDATE())) and visit.date_created <= DATEADD(HOUR, 16, DATEADD(d,-6,DATEDIFF(d,0,GETDATE()))))
)
Have you tried the following where clause instead?
WHERE visit.pkey=action.pkey and (visit.is_bot = 0)
AND visit.date_created >="2017-03-22 18:29:59"
AND visit.date_created <="2017-03-23 14:29:59"
3. Edit
OK, since OP wants something different again - and why not ;-) - here is another solution that might (or might not) solve his problem:
SELECT
COUNT( CASE WHEN d between
adddate(curdate(), interval -7 day) AND addtime(adddate(curdate(), interval -7 day),'16:00:00')
THEN 1 END ) dm7,
COUNT( CASE WHEN d between
adddate(curdate(), interval -6 day) AND addtime(adddate(curdate(), interval -6 day),'16:00:00')
THEN 1 END ) dm6,
COUNT( CASE WHEN d between
adddate(curdate(), interval -5 day) AND addtime(adddate(curdate(), interval -5 day),'16:00:00')
THEN 1 END ) dm5,
COUNT( CASE WHEN d between
adddate(curdate(), interval -4 day) AND addtime(adddate(curdate(), interval -4 day),'16:00:00')
THEN 1 END ) dm4,
COUNT( CASE WHEN d between
adddate(curdate(), interval -3 day) AND addtime(adddate(curdate(), interval -3 day),'16:00:00')
THEN 1 END ) dm3,
COUNT( CASE WHEN d between
adddate(curdate(), interval -2 day) AND addtime(adddate(curdate(), interval -2 day),'16:00:00')
THEN 1 END ) dm2,
COUNT( CASE WHEN d between
adddate(curdate(), interval -1 day) AND addtime(adddate(curdate(), interval -1 day),'16:00:00')
THEN 1 END ) dm1,
COUNT( CASE WHEN d between
curdate() AND addtime( curdate() ,'16:00:00')
THEN 1 END ) today
FROM (select '2017-03-17 15:00:01' d
union all select '2017-03-19 14:00:01'
union all select '2017-03-19 12:00:01'
union all select '2017-03-19 13:00:01'
union all select '2017-03-19 11:00:01'
union all select '2017-03-20 11:20:01'
union all select '2017-03-20 11:30:01'
union all select '2017-03-20 10:40:01'
union all select '2017-03-20 10:23:01' ) dates
This is an isolated query that works directly on the sample data given in the subquery. It results in the following list ("dm1"=day minus 1):
dm7 | dm6 | dm5 | dm4 | dm3 | dm2 | dm1 | today
1 | 0 | 4 | 4 | 0 | 0 | 0 | 0
You can test it here: http://rextester.com/ITLBL24540

MYSQL Count with INNER JOIN not working

I have two tables
1) outreach
id profile_id url
-------------------------
1 2 www.test.com
2 3 www.google.com
3 4 www.example.com
4 2 www.test2.com
5 2 www.test3.com
6 2 www.test4.com
2). outreach_links
id outreach_id start_date created_at cost status
-----------------------------------------------------------------------
1 1 2016-12-01 00:00:00 2016-12-07 00:00:00 100.00 Approved
2 1 2016-12-02 00:00:00 2016-12-09 00:00:00 120.00 Approved
3 1 NUll 2016-12-28 00:00:00 20.00 Pending
4 1 2016-12-05 00:00:00 2016-12-10 00:00:00 35.00 Approved
5 1 2016-12-07 00:00:00 2016-12-13 00:00:00 10.00 Approved
6 2 2016-12-10 00:00:00 2016-12-15 00:00:00 10.00 Pending
7 2 2016-12-13 00:00:00 2016-12-18 00:00:00 10.00 Approved
8 2 2016-12-01 00:00:00 2016-12-28 00:00:00 10.00 Pending
9 2 2016-12-04 00:00:00 2016-12-21 00:00:00 10.00 Approved
10 2 2016-12-09 00:00:00 2016-12-22 00:00:00 15.00 Pending
I am trying to do a count by Month/Year and I thought its working but I think its not working because of "profile_id" issue here is my query:
select monthname(date) as Month, year(date) as Year, month(date) as Mn, UNIX_TIMESTAMP(CONCAT(year(date),"-",month(date),"-","01")) as tt,
(select count(*) from outreach_links where year(outreach_links.created_at) = year and month(outreach_links.created_at) = month and status = "Pending" and created_at>="2016-12-01 00:00:00" and created_at<="2016-12-31 00:00:00") as pp,
(select count(*) from outreach_links where year(outreach_links.start_date) = year and month(outreach_links.start_date) = month and status = "Approved" and start_date>="2016-12-01 00:00:00" and start_date<="2016-12-31 00:00:00") as aa,
(select sum(cost) from outreach_links where year(outreach_links.start_date) = year and month(outreach_links.start_date) = month and status = "Approved" and start_date>="2016-12-01 00:00:00" and start_date<="2016-12-31 00:00:00") as cc
from
(select year(outreach_links.created_at) as year, month(outreach_links.created_at) as month, outreach_links.created_at as date
from outreach_links
inner join outreach on outreach.id = outreach_links.outreach_id
where outreach_links.created_at>="2016-12-01 00:00:00" and outreach_links.created_at<="2016-12-31 00:00:00" and outreach.profile_id=2
union
select year(outreach_links.start_date) as year, month(outreach_links.start_date) as month, outreach_links.start_date as date
from outreach_links
inner join outreach on outreach.id = outreach_id
where start_date>="2016-12-01 00:00:00" and start_date<="2016-12-31 00:00:00" and outreach.profile_id=2 ) t1
group by year, month
order by date
So I am doing a date range from "2016-12-01 00:00:00" to "2016-12-31 00:00:00" these could be any date range inputed by the user , and try to do a count based on outreach.profile_id = 2 , my output is wrong its counting everything for all profile_ids, I am not sure why
Note: this is just a sample of the tables , there might be more records and the user inputed Date range from to could be different , I want to group them by Month / Year
here is my output: ( its counting ALL records)
array:1 [▼
0 => {#394 ▼
+"Month": "December"
+"Year": "2016"
+"Mn": "12"
+"tt": "1480568400.000000"
+"pp": "4"
+"aa": "6"
+"cc": "285.00"
}
]
Which is wrong it should count only for profile_id=2 , here is the DESIRED output I want:
array:1 [▼
0 => {#394 ▼
+"Month": "December"
+"Year": "2016"
+"Mn": "12"
+"tt": "1480568400.000000"
+"pp": "1"
+"aa": "4"
+"cc": "265.00"
}
]
As you can see the 3 counts are wrong they suppose to be:
"pp": "1"
"aa": "4"
"cc": "265.00"
here is what I am looking for:
1). **"pp" is Total Pending** Count when status="Pending" based on created_at
2). **"aa" is Total Approved** Count when status="Approved" based on start_date
3). **"cc" is Total Cost** Sum of All cost when Status="Approved" and based on start_date
4). Group by Month & Year of the user imputed Date Range
here is a SQLFIDDLE >> http://sqlfiddle.com/#!9/87dfa8/1
can you please help me fix it?
Thanks
I think you want something like this:
SELECT MONTHNAME(d.date) AS Month
, YEAR(d.date) AS Year
, MONTH(d.date) AS Mn
, SUM(IF(l.status = 'Pending' AND l.created_at >= d.date AND l.created_at < d.date + INTERVAL 1 MONTH ,1 ,0)) AS pp
, SUM(IF(l.status = 'Approved' AND l.start_date >= d.date AND l.start_date < d.date + INTERVAL 1 MONTH ,1 ,0)) AS aa
, SUM(IF(l.status = 'Approved' AND l.start_date >= d.date AND l.start_date < d.date + INTERVAL 1 MONTH ,l.cost,0)) AS cc
FROM ( SELECT '2016-12-01' + INTERVAL 0 MONTH AS date ) d
JOIN outreach o
ON o.profile_id = 2
LEFT
JOIN outreach_links l
ON l.outreach_id = o.id
AND ( ( l.start_date >= d.date + INTERVAL 0 MONTH
AND l.start_date < d.date + INTERVAL 1 MONTH
)
OR ( l.created_at >= d.date + INTERVAL 0 MONTH
AND l.created_at < d.date + INTERVAL 1 MONTH
)
)
GROUP BY d.date
EDIT
To specify the end date of the range along with the start date, the inline view d can return two date values. And the outer query can reference the second date value, in this example d.end_date, as well as the start of the range d.date.
SELECT MONTHNAME(d.date) AS Month
, YEAR(d.date) AS Year
, MONTH(d.date) AS Mn
, SUM(IF(l.status = 'Pending' AND l.created_at >= d.date AND l.created_at < d.end_date,1 ,0)) AS pp
, SUM(IF(l.status = 'Approved' AND l.start_date >= d.date AND l.start_date < d.end_date,1 ,0)) AS aa
, SUM(IF(l.status = 'Approved' AND l.start_date >= d.date AND l.start_date < d.end_date,l.cost,0)) AS cc
FROM ( SELECT '2016-12-01' + INTERVAL 0 MONTH AS date
, '2016-12-16' + INTERVAL 0 MONTH AS end_date
) d
JOIN outreach o
ON o.profile_id = 2
LEFT
JOIN outreach_links l
ON l.outreach_id = o.id
AND ( ( l.start_date >= d.date
AND l.start_date < d.end_date
)
OR ( l.created_at >= d.date
AND l.created_at < d.end_date
)
)
GROUP BY d.date, d.end_date

date : group by month from day 2 to day 1 next month

I have query like this :
SELECT EXTRACT(MONTH FROM d.mydate) AS synmonth, SUM(apcp) AS apcptot
FROM t_synop_data2 d
WHERE d.mydate
BETWEEN '2011-01-01' AND '2011-12-31'
AND d.idx_synop = '06712'
GROUP BY synmonth
This query adds all rain (apcp) in a month like this :
1 32.8 => from 2011.01.01 to 2011.01.31
2 27.2 => from 2011.02.01 to 2011.02.28
3 21.0
4 21.8
5 88.5
6 131.4
7 118.6
8 57.1
9 80.9
10 84.6
11 1.1
12 143.5 => from 2011.12.01 to 2011.12.31
That's what I want, but with a little difference.
This difference is that i have to adds apcp from day 2 in the month to day 1 next month and then return a result like above.
1 132.8 => from 2011.01.02 to 2011.02.01
2 27.2 => from 2011.02.02 to 2011.03.01
3 21.0
4 21.8
5 88.5
6 131.4
7 118.6
8 57.1
9 80.9
10 84.6
11 1.1
12 143.5 => from 2011.12.02 to 2012.01.01
I tried something with add_date(), extract() or date_format() but without result.
Thank you for your answer
Vince
Here is the query :
SELECT EXTRACT(MONTH FROM ADDDATE(d.mydate,-1) ) AS synmonth
, SUM(apcp) AS apcptot
FROM t_synop_data2 AS d
WHERE ADDDATE(d.mydate,-1) BETWEEN '2011-01-01' AND '2012-12-31'
AND d.idx_synop = '06712'
GROUP BY synmonth
You can check the result by adding two columns like this:
SELECT EXTRACT(MONTH FROM ADDDATE(d.mydate,-1) ) AS synmonth
, SUM(apcp) AS apcptot
, MIN(d.mydate) AS date_min
, MAX(d.mydate) AS date_max
FROM t_synop_data2 AS d
WHERE ADDDATE(d.mydate,-1) BETWEEN '2011-01-01' AND '2012-12-31'
AND d.idx_synop = '06712'
GROUP BY synmonth
You can group by EXTRACT(MONTH FROM d.mydate - INTERVAL 1 DAY)
SELECT EXTRACT(MONTH FROM d.mydate) AS synmonth, SUM(apcp) AS apcptot
FROM t_synop_data2 d
WHERE d.mydate
BETWEEN '2011-01-01' AND '2011-12-31'
AND d.idx_synop = '06712'
GROUP BY EXTRACT(MONTH FROM d.mydate - INTERVAL 1 DAY)