Count of specific decimal values in a column in SSRS Table - reporting-services

I am trying to get a sum of people of a specific age. AgeInYears is a Decimal.
I have tried a sum and get 0 every time
=SUM(IIF( Fields!AgeInYears.Value = 15, 1, 0 ) )
If I do a count I get 68 which is still incorrect
=Count(IIF( Fields!AgeInYears.Value = 15, 1, 0 ) )
I'm not sure if I am comparing to a decimal correctly. When I use my query in SQL, then use a pivot table on the data I'm able to find the answer as 47 (I'm much better with excel than SSRS). But in SSRS I can only get a 0 or 68 Value.
EDIT
I am calculating the AgeInYears myself in my Query via
cast(cast(datediff(month, invl.ChildDateOfBirth, fp.enddate) as decimal) / 12 as decimal) as AgeInYears
could this be related?

I was unable to solve whatever issue that SSRS was giving me when I attempted to count the ages.
Instead I have updated my query to
Select
cast(cast(datediff(month, invl.ChildDateOfBirth, fp.enddate) as decimal) / 12 as decimal) as AgeInYears
From Table
Where
cast(cast(datediff(month, invl.ChildDateOfBirth, fp.enddate) as decimal) / 12 as decimal) > 13
and
cast(cast(datediff(month, invl.ChildDateOfBirth, fp.enddate) as decimal) / 12 as decimal) as AgeInYears < 19
This ensures my data only contains ages that I want ( between 14-18.
Then in the SSRS table I created a row group over AgeInYears and did a simple
=Count(Fields!AgeInYears.Value)
in the text box to get the correct count for each Age.

Related

SUBSTRING_INDEX Not Warking in Mysql

I am trying to find max invoice:
SELECT IFNULL(MAX(SUBSTRING_INDEX(invoice,'I', -1)) + 1, 1) AS invoice
FROM sales
SQL Fiddle
When I run this SQL query, it can not count more than 10.
invoice
20221026P1I1
20221026P1I2
20221026P1I3
20221026P1I4
20221026P1I5
20221026P1I6
20221026P1I7
20221026P1I8
20221026P1I9
20221026P1I10
20221026P1I11
20221026P1I12
I am trying to find max invoice 12 + 1 = 13
Your use of SUBSTRING_INDEX() is correct, however you should cast the string value to a bona fide integer:
SELECT COALESCE(MAX(CAST(SUBSTRING_INDEX(invoice, 'I', -1) AS UNSIGNED)), 1) AS invoice
FROM sales;
The problem with trying to find the max of the text substrings themselves is that text numbers sort lexicographically, e.g.
1
10
11
2
23
But this isn't the behavior you want, you want the numeric maximum. Hence we should cast these substrings and then compare.
Side note: You could have avoided this problem entirely by maintaining a pure numeric invoice number column. You may want to change your table design to include such a column.

Pivot with changing dates

I have a script with result set something like this:
-- #Test (temptable)
Branch_Name C_Date Percentage
Branch 1 20140107 90
Branch 1 20140108 82
Branch 2 20140107 85
Branch 2 20140108 86
I would like to pivot this data, however the C_Date is populated to get 7 days back:
WHERE (1 = 1) AND
(tTable.C_Date > CONVERT(VARCHAR(10),GETDATE() -7, 112)) AND
(tEnter.C_Date < CONVERT(VARCHAR(10),GETDATE() -1, 112)).
I've tried
Select * from #Test
pivot (avg (Percentage) for C_date in ([20140107],[20140108])) as PivotTable
and it gives me the data I want (see below),
Branch_Name 20140107 20140108
Branch 1 90 82
Branch 2 85 86
but how do I get the pivot to look at dates populated by the GETDATE? I've tried putting the GETDATE command in each [] but that obviously didn't work.
** Note, my example shows 2 days, but my query is for 7 days back, not including the day it's being run.
Any help appreciated - thank you!
Instead of trying to work with the dates, try working with "the number of days between C_Date and today".
So early on (in a subquery or CTE) you do DATEDIFF(day,C_Date,GETDATE()) as NumDays.
You can then filter your where as WHERE NumDays between 1 and 7 and your pivot as:
pivot (avg (Percentage) for NumDays in ([1],[2],[3],[4],[5],[6],[7])) as PivotTable
Now, that handles most of what you need. The one thing we can't do (in plain SQL) is to convert those column names back into dates - because any particular SQL query has to produce a result set with a fixed "shape" - the number, names and types of the columns are fixed.
But hopefully that's enough to do in SQL, and if you do need to convert back into date headings, that can be done with whatever is consuming this result set.

TSQL SELECT based on a condition

I am trying to do a select from CTE based on a condition.
There is a variable I've declared for today's period (#PRD). It holds the value of what period we are currently in.
Now I would like to do a selection from a table that will restrict what information is returned based on whether we are in the first half of the year or not.
For instance, we are in period 2 so I want everything returned from my CTE which falls between PRD 1 and 5. IF we were in say period 6 (after 5), then yes I'd want everything returned from the table.
This is the pseudocode of what I'm trying to accomplish:
SELECT
CASE
WHEN #PRD <= 5
THEN (SELECT * FROM DISPLAY WHERE PERIOD IN (1,2,3,4,5))
ELSE (SELECT * FROM DISPLAY)
END
I'm getting an error:
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
Please any thoughts on how I can do this?
Thanks x
EDITED/UPDATED:
More of the code involves a CTE and is really long. Bottom line is lets say I have this CTE
;WITH DISPLAY as (
select * from lots_of_things
)
SELECT * FROM DISPLAY
Having done a regular select on this CTE, it returns data that looks like this:
PERIOD (INT) DEPARTMENT GROUP BUDGET
1 ENERGY HE 500
2 ENERGY HE 780
3 ENERGY HE 1500
4 ENERGY HE 4500
5 ENERGY HE 400
6 ENERGY HE 3500
7 ENERGY HE 940
8 ENERGY HE 1200
I want it to show me just the top 5 rows if we the current period is 1,2,3,4,5. But to display ALL table rows if we are in any other period like 6,7,8,9 and onwards. The current period is held in the variable #PRD which is derived from doing a comparison of today's date with ranges held in a table. The value is accurate and also type INT
Hope this helps
SQL FIDDLE
This will work:
SELECT * FROM DISPLAY WHERE (#PRD > 5 OR PERIOD IN (1, 2, 3, 4, 5))
If this code confuses you, what's happening is that we check if #PRD > 5 and if that returns true, our expression is always true so we return all the rows.
If the variable is less or equal to 5 (like you checked in your example), the first check is false and then we check if the period is the list.
This might be a solution:
IF #PRD <= 5
SELECT * FROM DISPLAY WHERE PERIOD IN (1,2,3,4,5)
ELSE
SELECT * FROM DISPLAY
UPD
In this case you should use variable instead of CTE, if it's possible.
DECLARE #PRD INT;
SELECT #PRD = PERIOD FROM SOME_TABLE WHERE ...

Is any way to convert decimal to time in MySQL?

I created a field called 'hours_spent' in MySQL using the decimal datatype to store time. The values are stored like this 1.30, 2.30 etc... (for 1hr30min, 2hr30min).
I want to calculate the sum of various time values.
The sum of time is not what I expected: 1.30 + 2.30 = 3.60, whereas I expected 4.00.
I used the SUM function in MySQL to count the hours_spent field. If the values are 0.30 + 1.50 = 1.80, whereas I expected 2.20.
My first mistake was to use the decimal type instead of the time datatype, but I cannot change datatype.
So, is there any way to sum the time values and get result as I expect?
Thanks
I prepared you a demo at sqlfiddle, you can try it there if you want:
http://www.sqlfiddle.com/#!2/c9afc/2
Here are the query samples:
select #indexer:=instr(dateasdecimal, '.')
, left(dateasdecimal, #indexer-1) * 60 + substr(dateasdecimal, #indexer+1) as totalMinutes
from testtable;
select #indexer:=instr(dateasdecimal, '.')
, sum(left(dateasdecimal, #indexer-1) * 60 + substr(dateasdecimal, #indexer+1)) as totalMinutes
from testtable;
Note: Please don't forget to accept answers to your questions:
https://meta.stackexchange.com/a/65088/200585
To convert a decimal into seconds, you could use this:
truncate(hours_spent,0)*60+(hours_spent-truncate(hours_spent,0))*100
and then you can do the sums easily. Then you can convert back seconds to the decimal format with this:
truncate(seconds/60,0)+truncate(mod(seconds, 60)/100,2)
You could always turn the decimals into a string, cast as time, then sum that time using time_to_sec and produce a formatted time with sec_to_time. Of course, it would be much better to be storing those times a different way, even if it involves converting the entire dataset.
SELECT sec_to_time(sum(time_to_sec(goodTime))) FROM (
SELECT CAST(badTime AS TIME) AS goodTime FROM (
SELECT REPLACE(badTime, '.', ':') AS badTime FROM (
SELECT CAST(badTime AS dec(4,2)) AS badTime FROM (
SELECT 1.3 AS badTime
UNION select 2.3
) z
) y
) x
) w

SSRS 2008 Dataset Filtering - SUM / Break down by month

I have a dataset that is going to get passed to an SSRS report that looks like this:
CODE TEXT COUNT MONTH
100 ABC 20 January
100 ABC 10 February
200 DEF 15 January
200 DEF 15 February
300 GHI 0 x
400 JKL 10 January
This 'x' indicates there is no data for that code/text for the current year, however, I still need it to display. In SSRS I want to have a column to display for the current month (February) and a column to display for year to date:
CODE TEXT MONTH_TO_DATE YEAR_TO_DATE
100 ABC 10 30 [20 + 10]
200 DEF 15 30 [15 + 15]
300 GHI 0 0 [0]
400 JKL 0 10 [0 + 10]
Is this possible in SSRS 2008?
This is going to have to be done in SQL so it would be easier to adjust the SQL if you posted what you have already, rather than the data resulting from that SQL.
Anyway, we have to find a way to know it is the current month and display it, which we can do with the SQL CASE statement. Maybe you have a date field you can query which might be cleaner than below, but I'll just run with the data as you have provided (that is, we just have a month name which we compare to the current month using the DATENAME and GETDATE SQL functions - obviously this doesn't work if you have multiple years of data as every February will be aggregated into the current month, but you get the idea for what to do):
SELECT [CODE], [TEXT],
SUM(CASE WHEN [MONTH] = DateName(month, GetDate()) THEN [COUNT] END) AS CurrentMonth,
SUM([COUNT]) AS YearToDate
FROM MyTable
GROUP BY [CODE], [TEXT]
ORDER BY [CODE], [TEXT]
Now, in your comment on Vlad's answer you say you can't do a SUM(COUNT(fieldname)) which you can actually do if you use nested queries, like so:
SELECT [CODE], [TEXT], SUM([COUNT]) AS Total
FROM ( -- This is a nested query
SELECT [CODE], [TEXT], COUNT(somefield) AS [COUNT]
FROM MyTable
)
GROUP BY [CODE], [TEXT]
ORDER BY [CODE], [TEXT]
If you want to display x for the zero values then use the following Format for the YearToDate cell:
#,##0;-#,##0;x
This can be done in either SQL or SSRS - doing it in SQL (as described by Chris Latta) should be simpler and more efficient, but if that option is not available, here is how to do it in SSRS:
Add a 4-column table to the report, with the appropriate dataset.
Add a group (including group footer) on your CODE and TEXT columns to the table.
Add your CODE and TEXT values to the group footer.
Delete (or hide) the Details section row on your report.
Enter the following expression into the appropriate cell in the group footer row for the year-to-date column:
=Sum(Fields!COUNT.Value)
Enter the following expression into the appropriate cell in the group footer row for the month-to-date column:
=Sum(iif(MonthName(DatePart("m",Now()))=Fields!MONTH.Value,Fields!COUNT.Value,0))
I think you should return this from the sql select/stored procedure. You should use a LEFT JOIN i think for those 0 results