SSRS - avg function by subtotals - reporting-services

I have details, subtotals and totals.
When I put avg function in totals line I have avg of every row.
I need avg of subtotals
How to do it?
week1
day1..... 2
day3..... 3
day4..... 4
day6..... 2
total.... 11 sum()
week2
day1..... 3
day2..... 2
total..... 5 sum()
Total
........... 16 sum() OK
............ 2,66666 avg() here should be (11+5)/2 =8
Result after implementing solution

I created a dataset to replicate your sample data as follows:
DECLARE #t TABLE (week int, day int, amount int)
INSERT INTO #t VALUES
(1, 1, 2),
(1, 3, 3),
(1, 4, 4),
(1, 6, 2),
(2, 1, 3),
(2, 2, 2)
SELECT * FROM #t
I then built a simple tablix as you had done (more or less)
I included the incorrect results you had for illustration and then added a new expression to calculate this correctly.
The result looks like this
You can ignore the other datasets, this is just a report I use for testing. Only dataset3 is used here.
The expression used was this
=Sum(Fields!amount.Value) / CountDistinct(Fields!week.Value)
You'll just need to edit this to match your field names. It basically just sums all the detail amounts then divides by the number of distinct weeks in the dataset.

Related

SSRS Show table list in sequence

I have a list of data, with sequence id 1, 2, 3, ..., 9
I want to insert them into SSRS report in the form of 3x3 table, arranged by sequence id
1 2 3
4 5 6
7 8 9
I should use list, or table, or matrix? Any solution for this arrangement? Thanks
I would typically use a matrix for this. You can calculate the row and column numbers for each row of data in your table and then use that for your row and column groups in the matrix.
Here's an example...
Note: You might not have or want the 'label' field so just swap this out for whichever field you want to show when we get to the report design.
Here's some sample data with the Row and Col calculated
DECLARE #t TABLE (Seq int, Label varchar(10))
INSERT INTO #t VALUES
(1, 'AAAAA'), (5, 'BBBBB'), (10, 'CCCCC'),
(20, 'DDDDD'), (50, 'EEEEE'), (100, 'FFFFF'),
(101, 'GGGGG'), (102, 'HHHHH'), (210, 'IIIII')
SELECT
*
, ColN = (SeqOrder-1) %3
, RowN = (SeqOrder-1) / 3
FROM (SELECT *, ROW_NUMBER() OVER(ORDER BY Seq) AS SeqOrder FROM #t) t
The inner query just assigns the SeqOrder as 1 thru 9. We then use this SeqOrder value to determine the row and column
This gives us the following dataset
Then we just add a matrix to our report
Next, drag the ColN field to the "Columns" placeholder, the RowN field to the "Rows" placeholder and the Label field (or whatever field you want to display) to the "Data" placeholder.
Run the report and you get this
Optionally, you can remove the first row and column (but NOT the associated group) and just leave the data cell.
Now when we run it, we get this.

SQL: find intervals of step function

I have a table with 2 columns:
id INT PRIMARY_KEY
y FLOAT
The value in column "y" is guaranteed to be in 2 ranges:
small values: [0.18 - 0.20]
big values: [2.3 - 2.4]
It is known what "y" column in table has the following pattern: several records with small values then several records with big values then again several small and several big and so on. The number of consecutive records with the same range is not known and it is not fixed (vary). I need to find the id's (PK column) for beginning and ends of all intervals. Is it possible to do it in SQL?
(1; 0.19) (2; 0.18) (3; 0.19) (4; 2.3) (5; 2.4) (6; 2.3) (7;0.19)
Expect output: (1, 'start of small'), (3, 'end of of small'), (4, 'start of big'), (6, 'end of big'), (7, 'start of small')

MySQL: count consecutive rows with the same value

I have read a few similar questions on counting consecutive rows, but none of them gave me a clear answer. I hope someone could give me some help with my problem. I have the following table as an example.
create table medical
(PatientID int,
Date Date,
TookTest int
);
insert into medical(PatientID, Date, TookTest)
values
(1, '2014-01-01', 1),
(1, '2014-01-05', 1),
(1, '2014-01-10', 1),
(2, '2014-01-01', 1),
(2, '2014-01-10', 0),
(2, '2014-01-20', 1),
(3, '2014-01-01', 1),
(3, '2014-01-07', 1),
(3, '2014-01-12', 1),
(3, '2014-01-21', 1),
(4, '2014-01-03', 1),
(4, '2014-01-05', 1),
(4, '2014-01-22', 0),
(4, '2014-01-27', 1)
This table is used to find out which patient took a medical test on certain dates. The PatientID and date columns are pretty self-explanatory. The last column, TookTest is a binary indicator column where 1 indicates that a patient took a test and 0 otherwise. The patientID and date are sorted at the time of this table's creation. I would like to count the number of patients who took tests at least 3 times consecutively. In our example, PatientID 1 and 3 took 3 or more tests. So the answer is 2. Could anyone show me how to write a query in MySQL? Thanks for your help in advance!
SELECT
m_id
FROM(
SELECT
m.PatientID AS m_id,
m.Date AS m_date,
m.TookTest,
IF(m.TookTest = 1 AND #b = m.PatientID, #a := #a +1, #a := 0) AS new_count,
#b := m.PatientID
FROM medical m
JOIN (
SELECT
#a := 0,
#b := 0
) AS t
) AS TEMP
WHERE new_count >= 2
GROUP BY m_id
this does the calculation for you.. only thing is it looks a little weird because the count starts at 0 instead of 1 so if its 3 consecutive the count will be 2. this does what you requested..... see the fiddle if you have questions http://sqlfiddle.com/#!2/22ba28/12
This code also works, too.
set #test = 0, #id=0, #count=0;
select m.id, max(count)
from (
select
#count := if(TookTest = 1 and PatientID = #id, #count+1, 0) as count,
#test := Tooktest,
#id := PatientID as id
from medical) as m
group by m.id
having max(count) >=2;
This code counts the historical max consecutive rows of TookTest as opposed to the most recent consecutive row count (This distinction is not relevant here because the example data is too small to make any difference between most recent consecutive count and historical max consecutive count.)
My coding background is R, Python and Java. Possibly because of my personal particular coding experience, it is hard for me to grasp using join twice in this context. My code above is a way to get around it. I hope this answer helps others in a similar situation like mine.

SQL: Query formatting

I have a SQL query with three columns. The first is Year (categorical), the second is Site (categorical) and the last is temperature (float). The rows as unique combinations of Year X Site. For example:
Current query result
Year, Site, Temp
1, 1, x11
1, 2, x12
1, 3, x13
2, 1, x21
2, 2, x22
2, 3, x23
3, 1, x31
3, 2, x32
3, 3, x33
I would like to have each site as a different column, while keeping years as rows. For example:
Desired query result
Year, TSite1, TSite2, TSite3
1, x11, x12, x13
2, x21, x22, x23
3, x31, x23, x33
Any ideas on how to do a query that results in this format? I would not mind using a temporary table or a view to store the information.
Thanks in advance.
SELECT Year,MIN(CASE WHEN Site=1 THEN Temp ELSE 0 END) as Tsite1,
MIN(CASE WHEN Site=2 THEN Temp ELSE 0 END) as Tsite2,
MIN(CASE WHEN Site=3 THEN Temp ELSE 0 END) as Tsite3 FROM table GROUP BY Year
A pivot query is one approach (as mentioned in the comments) If you just want a comma-delimited list of sites, then you can do that with group_concat().
select year, group_concat(temp separator ', ' order by site) as temps
from t
group by year;
I realize this may not be exactly what you want -- you lose the type information for temp by converting it to a string for example. But then again, it may be what you need if you just want to see the temps or export them to another tool.

return rows where sum on a field less than a given value

My knowledge of MySQL is basic. I want to build a query to return all rows that sum a given value, in ascending order. I can't figure out how I can do that. Using sum() only returns one row. I've tried a subquery but it returns all rows. I don't want anybody do my work, I just want you to help me to figuring this out.
Anybody have an idea?
How to retrieve all rows that its filed "value" sum 30
Example:
given value: 30
field to sum: value
table:
id name value order
1 name1 3 1
2 name2 10 6
3 name3 13 3
4 name4 5 8
5 name5 20 25
So, the query must return:
id 1, id 3, id 2, id 4
Thanks in advance.
set #total:=0;
select id, name, value, `order`
from
(select
id, name, value, `order`,
#total:=if(#total is null, 0, #total)+`order` as total
from THE_TABLE
order by `order`
) as derived
where total<=30;
Using postgres as database, I think this does what you want. I'm not sure if it works similar in mysql:
CREATE TABLE test (
id int,
name varchar(50),
value int,
order_ int
);
INSERT INTO test values (1, 'name1', 3, 1);
INSERT INTO test values (3, 'name3', 13, 3);
INSERT INTO test values (2, 'name2', 10, 6);
INSERT INTO test values (4, 'name4', 5, 8);
INSERT INTO test values (5, 'name5', 20, 25);
SELECT * FROM (SELECT *, SUM(value) OVER (ORDER BY order_) sumvalues FROM TEST) a WHERE sumvalues <30