I've got this expression in a report:
=iif(
SUM(Fields!Amount.Value) >
(
SUM(iif
(
Fields!Date.Value >= DateAdd("d",-10,TODAY())
,Fields!Amount.Value
,CDbl(0)
)) / 10
)*2.0,
"Gold",
"Transparent"
)
It is controlling a table's text box background colour.
I was hoping it would change the cell to gold if the amount in the cell is twice, or more, than the 10 day average for that specific row.
The table shows 10 days of data and the dataset it uses has 60 days of data in it, so 10 day averages should be available.
Is the expression incorrect?
This is what it is currently creating - the two rows that are completely orange are obviously not what I want.
The issue is with the sum you are doing to create your average. It is really only summing the first number it encounters and then dividing by 10 and multiplying by 2. You need to change the scope of your sum to the entire dataset. Here's how I proved this out.
I took the second row of numbers in your table above as my example. Here's my query.
SELECT '1/15/14' AS dt, 1 AS value
UNION
SELECT '1/16/14' AS dt, 7 AS value
UNION
SELECT '1/17/14' AS dt, 5 AS value
UNION
SELECT '1/18/14' AS dt, 6 AS value
UNION
SELECT '1/19/14' AS dt, 4 AS value
UNION
SELECT '1/20/14' AS dt, 5 AS value
UNION
SELECT '1/21/14' AS dt, 5 AS value
UNION
SELECT '1/22/14' AS dt, 5 AS value
UNION
SELECT '1/23/14' AS dt, 6 AS value
UNION
SELECT '1/24/14' AS dt, 6 AS value
I created a tablix with dt in the columns value in the data. If I take your average calculation and put it in a row below, it will return 9.8 for every column.
I first used your fill expression to make sure I got the same results as you. Then I altered it to get the correct answer:
=iif(Sum(Fields!value.Value) >
(Sum(iif(Fields!dt.Value >= Dateadd("d",-10, today()), Fields!value.Value, CDbl(0)), "DataSet1")/10) * 2,
"Gold","White")
With the data I had, none of the cells should turn gold, and that is the result I got. If I change the value for 1/15 to 20 and then preview my table, that cell turns gold because 69/10*2 = 13.8 and 20 > 13.8.
Related
I have a table as below
id pausetime resumetime
-----------------------------------------------------
1 2021-09-22 14:21:34.023 2021-09-22 14:25:37.030
2 2021-09-22 14:37:47.810 2021-09-22 14:40:58.817
I want to subtract resumetime from pausetime for all the rows, then add that time so that I can get the total time between resume and pause, number of rows can be different .
How can I do that ?
I tried this
select
dbo.TimeDifference(cast(resumetime as time),
cast(pausetime as time)
but I have to do it for all the rows.
Please help me out.
We can use DATEDIFF here along with SUM:
SELECT SUM(DATEDIFF(ss, pausetime, resumetime)) AS total_diff_in_seconds
I have below requirement.
Input is like as below.
Create table Numbers
(
Num int
)
Insert into Numbers
values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15)
Create table FromTo
(
FromNum int
,ToNum int
)
Select * From FromTo
Output should be as below.
FromNum ToNum
1 5
6 10
11 15
Actual Requirement is as below.
I need to load the data for a column into a table which will have thousands of records with different no's.
Consider like below.
1,2,5,7,9,11,15,34,56,78,98,123,453,765 etc..
I need to load these into other table which is having FROM and TO columns with the intervals of 5000. For example in the first 5000 if i have the no's till 3000, my 1st row should have FromNo as 1 and ToNum as 3000. second row: if the data is not having till 10000 and the next no started as 12312(This is the 2nd Row FromNum) the ToNum value should be +5000 i.e 17312. Here also if we don't have the no's data till 17312 it need to consider the ToNum between the 12312 and 17312
Output should be as below.
FromNum ToNum
1 3205
1095806 1100805
1100808 1105806
1105822 1110820
Can you guys please help me with the solution for the above.
Thanks in advance.
What you may try in this situation is to group data and get the expected results:
DECLARE #interval int = 5
INSERT INTO FromTo (FromNum, ToNum)
SELECT MIN(Num) AS FromNum, MAX(Num) AS ToNum
FROM Numbers
GROUP BY (Num - 1) / #interval
I would like to create a named calculation field for age, and I want to declare a local variable inside an expression like the following, but it doesn't not work :
DECLARE
#age INT;
#age=DateDiff("yyyy",DATE_NAIS,getdate());
CASE WHEN #age<=10 THEN 1
WHEN #age>10 AND #age<=20 THEN 2
WHEN #age>20 AND #age<=35 THEN 3
ELSE 4
END
Correct, you cannot DECLARE a variable in the context of an expression in a SELECT, like you are trying to do.
You have a few different options, one of which digital.aaron gave in his comments.
Another is to create it as an artificial column in a CTE, and then select from the CTE instead of the table:
WITH cte AS (SELECT *, DateDiff("yyyy",DATE_NAIS,getdate()) AS age FROM MyTable)
SELECT CASE
WHEN age<=10 THEN 1
WHEN age>10 AND age<=20 THEN 2
WHEN age>20 AND age<=35 THEN 3
ELSE 4
END AS SomeColumn
FROM cte
This question is tagged with SSAS, so I'm guessing you're doing this in a cube? The following DAX formula will work as a calculated column in your model for what was described in your post. As stated in the comments DATEDIFF alone will only return the difference between the current year and the year the person was born, which is why YEARFRAC is used to obtain the fraction of a year, then this is rounded down to the nearest integer via the INT function. For example, someone who is 50 years, 364 days old would be considered 50, not 51. Since TRUE() is given as the first argument of the SWITCH function, this will evaluate each condition until a match is found.
PersonAge:=
var Age = INT(YEARFRAC(YourTable[DATE_NAIS], TODAY()))
RETURN
SWITCH
(TRUE(),
Age < 10, 1,
AND(
Age > 10,
Age <= 20), 2,
AND(
Age > 20,
Age <= 35), 3,
4)
(This is my first stack overflow question. So please let me know suggestions for posing a better question, if you cannot understand.)
I have a table of around 500 people(users) who are going up the stairs from floor x (0=x, max(y) = 50). A person can climb zero/one or many levels in a single go which corresponds to a single row of the table along with the time taken to do so in seconds.
I want to find average time taken to go from floor a to a+1 where a is any of the floor number. To do so I intend to divide every row of the mentioned table into rows which have start_level+1= end_level. Duration will be divided equally as shown in EXPECTED OUTPUT TABLE for user b.
GIVEN TABLE INPUT
start_level end_level duration user
1 1 10 a
1 2 5 a
2 5 27 b
5 6 3 c
EXPECTED OUTPUT
start_level end_level duration user
1 1 10 a
1 2 5 a
2 3 27/3 b
3 4 27/3 b
4 5 27/3 b
5 6 3 c
Note: level jumps are in integers only.
After getting expected output, I can simply create a column sum(duration)/count(distinct users) at a start_level level to get average time taken to get one floor above from each floor.
Any help is appreciated.
You can use a Numbers table to "create" the incremental steps. Here's my setup:
CREATE TABLE #floors
(
[start_level] INT,
[end_level] INT,
[duration] DECIMAL(10, 4),
[user] VARCHAR(50)
)
INSERT INTO #floors
([start_level],
[end_level],
[duration],
[user])
VALUES (1,1,10,'a'),
(1,2,5,'a'),
(2,5,27,'b'),
(5,6,3,'c')
Then, using a Numbers table and some LEFT JOIN/COALESCE logic:
-- Create a Numbers table
;WITH Numbers_CTE
AS (SELECT TOP 50 [Number] = ROW_NUMBER()
OVER(
ORDER BY (SELECT NULL))
FROM sys.columns)
SELECT [start_level] = COALESCE(n.[Number], f.[start_level]),
[end_level] = COALESCE(n.[Number] + 1, f.[end_level]),
[duration] = CASE
WHEN f.[end_level] = f.[start_level] THEN f.[duration]
ELSE f.[duration] / ( f.[end_level] - f.[start_level] )
END,
f.[user]
FROM #floors f
LEFT JOIN Numbers_CTE n
ON n.[Number] BETWEEN f.[start_level] AND f.[end_level]
AND f.[end_level] - f.[start_level] > 1
Here are the logical steps:
LEFT JOIN the Numbers table for cases where end_level >= start_level + 2 (this has the effect of giving us multiple rows - one for each incremental step)
new start_level = If the LEFT JOIN "completes": take Number from the Numbers table, else: take the original start_level
new end_level = If the LEFT JOIN "completes": take Number + 1, else: take the original end_level
new duration = If end_level = start_level: take the original duration (to avoid divide by 0), else: take the average duration over end_level - start_level
I'm working on a report that shows transactions grouped by type.
Type Total income
------- --------------
A 575
B 244
C 128
D 45
E 5
F 3
Total 1000
I only want to provide details for transaction types that represent more than 10% of the total income (i.e. A-C). I'm able to do this by applying a filter to the group:
Type Total income
------- --------------
A 575
B 244
C 128
Total 1000
What I want to display is a single row just above the total row that has a total for all the types that have been filtered out (i.e. the sum of D-F):
Type Total income
------- --------------
A 575
B 244
C 128
Other 53
Total 1000
Is this even possible? I've tried using running totals and conditionally hidden rows within the group. I've tried Iif inside Sum. Nothing quite seems to do what I need and I'm butting up against scope issues (e.g. "the value expression has a nested aggregate that specifies a dataset scope").
If anyone can give me any pointers, I'd be really grateful.
EDIT: Should have specified, but at present the dataset actually returns individual transactions:
ID Type Amount
---- ------ --------
1 A 4
2 A 2
3 B 6
4 A 5
5 B 5
The grouping is done using a row group in the tablix.
One solution is to solve that in the SQL source of your dataset instead of inside SSRS:
SELECT
CASE
WHEN CAST([Total income] AS FLOAT) / SUM([Total income]) OVER (PARTITION BY 1) >= 0.10 THEN [Type]
ELSE 'Other'
END AS [Type]
, [Total income]
FROM Source_Table
See also SQL Fiddle
Try to solve this in SQL, see SQL Fiddle.
SELECT I.*
,(
CASE
WHEN I.TotalIncome >= (SELECT Sum(I2.TotalIncome) / 10 FROM Income I2) THEN 10
ELSE 1
END
) AS TotalIncomePercent
FROM Income I
After this, create two sum groups.
SUM(TotalIncome * TotalIncomePercent) / 10
SUM(TotalIncome * TotalIncomePercent)
Second approach may be to use calculated column in SSRS. Try to create a calculated column with above case expression. If it allows you to create it, you may use it in the same way as SQL approach.
1) To show income greater than 10% use row visibility condition like
=iif(reportitems!total_income.value/10<= I.totalincome,true,false)
here reportitems!total_income.value is total of all income textbox value which will be total value of detail group.
and I.totalincome is current field value.
2)add one more row to outside of detail group to achieve other income and use expression as
= reportitems!total_income.value-sum(iif(reportitems!total_income.value/10<= I.totalincome,I.totalincome,nothing))