customizing the sort rows in a report - reporting-services

I'm trying to totally customize my report rows. Say I have a matrix report like this:
Category Smith Jones Johnson
Overhead 1,230.00 34.00 56.01
FTE (23.00) 105.00 2,389.00
RVU 3.00 787.00 89.00
Salary 44.00 782.00 9.00
Subsidy 11.00 4,561.00 389.00
TNS 4635.00 55.00 45.00
Is it possible to create a totally custom sort order? I would like to move RVU on top, then Salary, then TNS, etc. I found if I go into the Group Properties, I can define an expression like:
=iif(Fields!City.Value=”RVU”,”1″, iif(Fields!City.Value=”Salary”,”2″, iif(Fields!City.Value=”TNS”,”3″,”"...etc.
But that's very restrictive, and if I later want to move a row up or down, I have to go in and change all the numbers. What I'm looking for is a drag and drop approach that would let me change the order easily, and at any time.
Is this possible?

I would recommend adding a sort order to your dataset, it is the easiest to maintain, maybe a case sentence in your sql query,
Select Case when [Category]='RVU' then 1
when [Category]='Salary' then 2 end as Sortorder, [other], [columns]
then you can order by the sort order column
I can't think of an easy drag and drop solution to this problem

Related

Using Lookup and getting a count from each Dataset

I have two datasets and I'm using Lookup to get one result, but the total is only from one dataset. I've tried and tried, but I'm having no luck.
First Dataset is called MedCond
This is the Data:
Drug_Name
Start_Date
Stop_Date
InmateID
Drug_Indication
Created
ID
Second Dataset is called ProblemList
This is the Data:
Medical_Condition
Inmate_ID
Created
ID
Drug Indication and Medical Condition are the same. I want to get a combined total of both.
This only gives me the count of the Drug Indications (which I have them grouped on) =Count(Lookup(Fields!Drug_Indication.Value,Fields!Medical_Condition.Value,Fields!Medical_Condition.Value, "ProblemList"))
I feel like I've tried everything under the sun. I'm extremely exasperated. I'm trying to get a total of each of the conditions/Indications that come from each dataset. For instance, One condition/Indication might be Addiction. There may be four addictions in from the Drug_Indication in the MedCon dataset and five addictions from the Medical_Condition in the ProblemList. I want to see Addictions 9 on the table and so and so forth for each Drug Indication/Medical Condition.
Thanks in advance for your help! Save my sanity. :) I'm sure it's probably something simple?
Tara
Thank you. I've tried using the Inmate_ID and InmateID as the key to join, but I still end up with only one of counts of either Medical_Condition or Drug_Indication.
As an example, there might be 10 addictions in one and 15 addictions in the other. I need them to be grouped under the title addiction (and whatever other titles there might be) with the total being 25.
It would look something like this.
Example Look
Something like this is close, but the counts aren't quite right.
=Count(Lookup(Fields!InmateID.Value, Fields!Inmate_ID.Value, Fields!Medical_Condition.Value, "ProblemList")) + Count(Fields!Drug_Indication.Value)
Maybe it's the way I'm grouping? How do you group on a combination of values such as Medical_condition and Drug_Indication?
Thanks again!
Tara
I think you used the Lookup() wrong. When I look at your two datasets (for me) the key to join the two datasets would be Inmate_ID.
=Lookup(Fields!InmateID.Value, Fields!Inmae_ID.Value, Fields!Medical_Condition.Value, "SecondDatasetName")
This would result in a table like this (The last column comes form the lookup above):
Drug_Name | Start_Date | Stop_Date | InmateID | Drug_Indication | Created | ID | Medical_Condition
Now you can just get the total per column:
Drug_Name | Start_Date | Stop_Date | InmateID | Drug_Indication | Created | ID | Medical_Condition
Total1 Total2
To sum Total1 and Total2 you can add a new tablix and reference to the textbox totals like this:
=ReportItems!Total1TextboxName.Value + ReportItems!Total2TextboxName.Value

parameters for nested mysql views

Here is a table with barcodes which belongs to different warehouses.
Barcode | Warehouse
_____________________________
1111111 | A
2222222 | B
1111111 | C
3333333 | A
And here is a table with boxes containing barcodes.
Barcode | Box
_____________________________
1111111 | 0001
2222222 | 0002
Each warehouse's available stock is its amount in the first table, plus all the amount in boxes.
Example for warehouse A:
Barcode
_________
1111111 (from its warehouse)
3333333 (from its warehouse)
1111111 (from a box)
2222222 (from a box)
This is a simplified example. After retrieving the total amount of barcodes, I cross it with a lot of other queries and tables to transform it into a human-readable report.
Ok,
The idea would be a server-side query.
Every client (VBA msaccess) would retrieve the query and filter it using its warehouse code.
Warehouse A would call it like this:
select * from finalQuery where warehouse like 'A' <--- BUT it won't work, because boxes' barcodes haven't the warehouse field, thus, they would be excluded.
The "where" clause should be performed before the UNION ALL.
Would it be possible to use parameters in order to exclusively retrieve a warehouse's barcodes + all boxes' barcodes in a server-side query? Even though the user calls the last query with its code, it should push the parameter down to the first nested query.
Or any other trick? Maybe my scheme is wrong?
The problem manipulating queries in the client side, is that it becomes painstakingly SLOW, because as I said, after joining barcodes, I use the resulting query for building other queries.
Hope I explaied it clearly. It is somewhat complex to explain. I would appreciate any suggestion, trick, idea, etc
Thank you.
I think what you're looking for is a JOIN statement. You can join the Barcode-Warehouse table with the Barcode-Box table using the common Barcode column. This article is a great explanation: http://www.tutorialspoint.com/mysql/mysql-using-joins.htm.
Your server side query will end up being something like this:
SELECT Barcode, Box, Warehouse FROM Barcode-Warehouse LEFT JOIN Barcode-Box USING (Barcode);
This should result in a result set that has Barcode, Box, and Warehouse on each line. Your users would then be able to filter that result by Warehouse and retrieve only the records that they are interested in.
Found a way to solve it:
Can I create view with parameter in MySQL?
I filter the first query by adding:
"where warehouse=function()"
When I call the final query, I add the parameter for the function as explained in the post. Easy, simple.
thank you

RowNumber for group in SSRS 2005

I have a table in a SSRS report that is displaying only a group, not the table details. I want to find out the row number for the items that are being displayed so that I can use color banding. I tried using "Rowcount(Nothing)", but instead I get the row number of the detail table.
My underlying data is something like
ROwId Team Fan
1 Yankees John
2 Yankees Russ
3 Red Socks Mark
4 Red Socks Mary
...
8 Orioles Elliot
...
29 Dodgers Jim
...
43 Giants Harry
My table showing only the groups looks like this:
ROwId Team
2 Yankees
3 Red Socks
8 Orioles
29 Dodgers
43 Giants
I want it to look like
ROwId Team
1 Yankees
2 Red Socks
3 Orioles
4 Dodgers
5 Giants
You can do this with a RunningValue expression, something like:
=RunningValue(Fields!Team.Value, CountDistinct, "DataSet1")
DataSet1 being the name of the underlying dataset.
Consider the data:
Creating a simple report and comparing the RowNumber and RunningValue approaches shows that RunningValue gives your required results:
You can easily achieve this with a little bit of vbcode. Go to Report - Properties - code and type something like:
Dim rownumber = 0
Function writeRow()
rownumber = rownumber + 1
return rownumber
End Function
Then on your cell, call this function by using =Code.writeRow()
As soon as you start using groups inside the tables, the RowNumber and RunningGroup functions start getting some weird behaviours, thus it's easier to just write a bit of code to do what you want.
I am not convinced all suggestions above provide are a one for all solution. My scenario is I have a grouping that has has multiple columns. I could not use the agreed solution RunningValue because I don't have a single column to use in the function unless I combine (say a computed column) them all to make single unique column.
I could not use the VBA code function as is for the same reason and I had to use the same value across multiple columns and multiple properties for that matter unless I use some other kind of smarts where if I knew the number of uses (say N columns * M properties) then I could only update the RowNumber on every NxM calls however, I could not see any count columns function so if I added a column I would also need to increase my N constant. I also did not want to add a new column as also suggested to my grouping as I could not figure out how to hide it and I could not write a vba system where I could call function A that returns nothing but updates the value (i.e. called only once per group row) then call another function GetRowNumber which simply returns the rownumber variable because the colouring was done before the call so I always had one column out of sync to the rest.
My only other 2 solutions I could think of is put the combined column as mentioned earlier in the query itself or use DENSE_RANK and sort on all group columns, i.e.
DENSE_RANK() OVER (ORDER BY GroupCol1, GroupCol2, ...) AS RowNumber

Design to represent employee check-in and check-out

I currently have a table which represents the start and stop work times of an employee:
id_employee int
check_in datetime
check_out datetime
It requires an update on check_out when the employee is finished.
Would it be preferable to have a table as follows ?
id_employee int
date_event datetime
event_type varchar, values can be CHECKIN or CHECKOUT.
To determine if an employee has already checked in all I have to is check if the last record for a given employee has an event_type of CHECKIN. Also, fetching a record and updating it is no longer necessary.
Is the second approach better ? Or do you have other suggestions ?
I know this post is outdated but, this is for someone who's still looking for solution:
Attendance Table Structure
id | int
employee_code | varchar
status | enum('check_in','check_out')
created | datetime
Data
id employee_code status created
1 EMP0001 check_in 2016-08-20 09:30:30
2 EMP0001 check_out 2016-08-20 18:15:00
3 EMP0002 check_in 2016-08-21 14:52:48
4 EMP0002 check_out 2016-08-21 21:09:18
Query
SELECT
A1.employee_code,
A1.created AS check_in_at,
A2.created AS check_out_at,
TIMEDIFF(A2.created, A1.created) AS total_time
FROM
tbl_attendances AS A1
INNER JOIN tbl_attendances AS A2
ON A1.employee_code = A2.employee_code
AND DATE(A1.created) = DATE(A2.created)
WHERE 1 = 1
AND A1.status = 'check_in'
AND A2.status = 'check_out'
AND DATE(A1.created) BETWEEN '2016-08-20'
AND '2016-08-21'
AND DATE(A2.created) BETWEEN '2016-08-20'
AND '2016-08-21'
ORDER BY A1.created DESC
Results
employee_code check_in_at check_out_at total_time
EMP0002 2016-08-21 14:52:48 2016-08-21 21:09:18 06:16:30
EMP0001 2016-08-20 09:30:30 2016-08-20 18:15:00 08:44:30
For specific employee add AND A1.employee_code = 'EMP0001' in WHERE clause
As usual, "it depends".
Option 1 is easier to build, and simpler to query. Finding out who checked in but didn't check out is a simple query; finding the total hours worked for each employee is also straightforward. This simplicity probably means it will be faster for common queries. The only drawback I see is that it is harder to extend. If you want to capture a different event type for "lunch break", for instance, you have to add extra columns.
Option 2 is more flexible - you can add new event types without changing your schema. However, simple queries - how many hours did employee x work in June - are quite tricky. You pay for the flexibility in significant additional effort.
So, it depends what you mean by "better".
Format #2 is better because :
This table is just a punch record entry - Even if it has anomalies it doesn't matter.
Going forward this table will expand, for example you might want to introduce two more events INTERVAL_OUT, INTERVAL_IN. Second format will keep it simple.
If possible use event_type_id instead of event_type and another table event_type or just a constant array eg.
array_event_name = array (1=>CHECKIN, 2=>CHECKOUT, 3=>INTERVAL_IN, 4=>INTERVAL_OUT)
i would go with the second one.
however, the main questions and business rules will be the same and answerable by either approach.
Option #1
With the first option, the database itself can better protect itself from some anomalies1. Some anomalies are still possible2, but it's a start.
On the other hand, InnoDB tables are clustered and secondary indexes in clustered tables can be expensive (see the "Disadvantages of clustering" in this article), which is something to consider if you need to query on check_out.
Option #2
With the second option, you are relying on the imperative code even for anomalies that can be prevented purely declaratively with the database design.
On a plus side, you are less likely to need secondary indexes.
Choice
So in a nutshell, go with the first option, unless you need a secondary index. If you do need the secondary index, depending on what kind of index covering you wish to achieve, you might go with either option.
1 Such as checking-out without first checking-in.
2 Such as checking-in again, without first checking-out, overlapping "stints", etc...
I would go with the first option here. Putting both time stamps in a single row will enhance your search time and will make your calculations easier.
Suppose you want to calculation work hours for an employee for a day. Your search will stop at the first line it matches and you will have all the required data. You wont have to dig any deeper which is not the case with option 2. Option 1 also reduces your table size by using only 1 row per check-in/check-out.
Option 2 does have one advantage though. When checking out, your database will have to do a search to update the data for option 1. For option 2, its just a write.
Considering the fact that you will search the data more than once, you can give up the direct insert advantage to gain a better structure and faster search. Although the final choice is up to you.
Good Luck!

Select "lowest value" from table for multiple "ids"

I read up last night on using the sql MIN() and I understand how it works now. However, I was wondering, how do I run
SELECT MIN(card_price)
FROM card_lookup_values
and display the lowest "price" for each individual card. A lot of the cards have 5-9 prices in the card_price column. I guess I was looking for:
card_id card_price
0001 2
0002 99
0003 22.3
You need a group by card_name.
Consider reading this tutorial on aggregate functions:
http://www.postgresql.org/docs/9.0/static/tutorial-agg.html