how do ssrs groups work? - sql

I'm trying to understand how ssrs formats the way data is presented. I have a table in ssms and a sp that gets the data from that table. The sp code is:
select *
from [CustData]
where 1 = 1
and (reportYear = #dbParam_reportYear or reportYear = #dbParam_reportYear-1 )
and marketCode=#dbParam_marketCode
and brandName=#dbParam_brandName
and (contactSegmentDesc=#dbParam_contactSegmentDesc)
order by reportYear ASC, reportMonth ASC
This obviously returns the data row by row i.e. if the report year param is 2014, then the rows with 2014 and then rows with 2013 data.
image:
This is then used in ssrs in a report but the data is presented by columns. The column group is like [segmentDesc] [reportMonth] [reportYear] followed by all the data that is retrieved.
image:
I need to know what is formatting the data output from row by row to column by column presentation. I do suspect its the column groups but need to confirm. I am new to this.
Getting difference of the values:

This can be conducted with use of SSRS matrix. Here is a nice tutorial: https://www.youtube.com/watch?v=zERexbgCG5A
The delta can be calculated with the following approach: https://social.msdn.microsoft.com/Forums/sqlserver/en-US/e77d6526-cadc-4d14-8ca3-997d58cb7c4a/ssrs-matrix-difference-between-columns?forum=sqlreportingservices
Notice the following:
=(Code.GetMaxValue(RunningValue(Fields!Month.Value,CountDistinct,"Services"),(Fields!Amount.Value)-Previous(FIRST(Fields!Amount.Value))))

Related

Perform calculation without having to do it manually for each column?

I have the following view set up in SQL Server:
VIEW
(left table: population data per year; middle table: municipalities; right table: municipality areas in km²)
Query
SELECT
dbo.T_GEMEINDE.GKZ, dbo.T_GEMEINDE.NAME,
dbo.T_BASE_DAUERSIEDLUNGSRAUM_GEMEINDE.FLAECHE_KM2 / dbo.T_BASE_DAUERSIEDLUNGSRAUM_GEMEINDE.DAUERSIEDLUNGSRAUM_KM2 AS [ges. Fläche / Dauersiedlungsr.],
dbo.T_BASE_GEMEINDE_BEVOELKERUNG_JAHR_BEGINN.J2017 / dbo.T_BASE_DAUERSIEDLUNGSRAUM_GEMEINDE.FLAECHE_KM2 AS [ges. Bevölkerungsdichte],
dbo.T_BASE_GEMEINDE_BEVOELKERUNG_JAHR_BEGINN.J2017 / dbo.T_BASE_DAUERSIEDLUNGSRAUM_GEMEINDE.DAUERSIEDLUNGSRAUM_KM2 AS [Bevölkerungsdichte Dauersiedlungsraum]
FROM
dbo.T_BASE_DAUERSIEDLUNGSRAUM_GEMEINDE
INNER JOIN
dbo.T_GEMEINDE ON dbo.T_BASE_DAUERSIEDLUNGSRAUM_GEMEINDE.GKZ = dbo.T_GEMEINDE.GKZ
INNER JOIN
dbo.T_BASE_GEMEINDE_BEVOELKERUNG_JAHR_BEGINN ON dbo.T_GEMEINDE.GKZ = dbo.T_BASE_GEMEINDE_BEVOELKERUNG_JAHR_BEGINN.GKZ
The last column in the view contains a calculation (population density for 132 municipalities for a certain year) for the year 2017 and uses the column J2017 from the table seen on the left. This is the output (Bevölkerungsdichte Dauersiedlungsraum):
Current output:
OUTPUT
Desired output:
The rightmost column (Bevölkerungsdichte Dauersiedlungsraum) seen in the provided output screenshot has the output data of the calculation for the year 2017. The same output has to be generated for all the other years, but each as a separate column.
Question: how do I perform the calculation which you can see in the last column in the view for all years (J2017-J2050) without having to do it manually for each year column?
Thanks in advance.
if you want someone to provide you with a complete solution then you will need to supply:
CREATE TABLE statements for the 3 tables
INSERT INTO... statements to provide sample data for all 3 tables
However, if you just want a suggestion about how to approach this problem then I would use an UNPIVOT statement to create a view/table that
holds all the columns in dbo.T_BASE_GEMEINDE_BEVOELKERUNG_JAHR_BEGINN
apart from the "year" columns (J2017, J2018, j2019, ...)
adds a single "year" column with values from 2017 to 2050
adds a single value column to hold the population for each year
By joining your existing tables to this new table/view and grouping by your new "year" column you should achieve what you want

SQL Server - collapsing multiple row values into one field

I'm trying to produce the result shown in the "Desired Results" section (in SQL Server 2016) in my screenshot below, where the objections associated with each borrower number are in one column delimited by commas instead of separate rows.
I don't want to restructure my database - I just want to display the results as requested for a customer report. Thanks
I was able to use the STRING_AGG function which I didn't know existed to produce the results I need.
SELECT ht.Hearings_CaseID, Borrower_Number, STRING_AGG(Objection,',') AS Objection
FROM Hearings_Test ht INNER JOIN
Hearings_Objections_Test hot on ht.Hearings_CaseID = hot.Hearings_CaseID
GROUP BY
ht.Hearings_CaseID, Borrower_Number

How to Split a Column into 2 Columns in SQL

I have an SQL Query which extracts columns from a table that must be in this order
Item Id,
Parms,
Move list,
MsgId. I also have a couple of requirements in the query that must remain there such as UserCode = automation and the Date is set to one day prior to the current day.
An example of the Parms output for one row is such
CURRENT OUTPUT
Parms:
V51370,Move List,M-000001
--
REQUIRED OUTPUT
Media: v51370
Comments: Was Removed From
Move List: M-000001
What I want to do is split this Parms column into two separate columns that are in between the Item Id and Move list Column. The first Column should be called Media which extracts the first six characters from the Parms Column:v51370. The second column is comments and if the MsgId is 1 the comment should be: Was Removed from.
Can Anyone make any suggestions to a possible query I could test? I'm not sure where to fit the Parms column split in there. That would be greatly appreciated.
Please Note: I am using SQL Server Management Studio 2008, and the table name is JnlList.
1 SAMPLE ROW (SELECT * FROM JNLLIST):
ItemId: 2
Date: 20122102.124652563
Object: S-000001
MsgID: 1
Parms: V86143,Scratch List,S-000001
Delimiter: -
UserCode: Automation
ActionId: 5
List Type: S
to seperate the first 6 chars from the parms use
SELECT SUBSTRING(Parms,1,6) AS Media
FROM YOUR TABLE;
Then you can use a subquery with the same syntax to select the rest of the chars from the Parms column and put them into a seperate column

SQL - How to insert a subquery into a query in order to retrieve unique values

I am writing reports using Report Builder 3, and I need some help with an sql query to get unique values.
Using the following sample data:
I need to be able to get one single value for feeBudRec returned for each feeRef. The value of each feeBudRec is always the same for each individual feeRef (eg for every data row for feeRef LR01 will have a feeBudRec of 1177).
The reason why I need to get a single feeBudRec value for each feeRef is that I need to be able to total the feeBudRec value for each feeRef in a feePin (eg for feePin LEE, I need to total the feeBudRec values for LR01 and PS01, which should be 1177 + 1957 to get a total of 3134; but if I don't have unique values for feeBudRec, it will add the values for each row, which would bring back a total of 11756 for the 8 LEE rows).
My experience with writing SQL queries is very limited, but from searching the internet, it looks like I'll need to put in a subquery into my SQL query in order to get a single unique feeBudRec figure for each feeRef, and that a subquery that gets a minimum feeBudRec value for each feeRef should work for me.
Based on examples I've found, I think the following subquery should work:
SELECT a.feeRef, a.feeBudRec
FROM (
SELECT uvw_EarnerInfo.feeRef, Min(uvw_EarnerInfo.feeBudRec) as AvailableTime
FROM uvw_EarnerInfo
GROUP BY
uvw_EarnerInfo.feeRef
) as x INNER JOIN uvw_EarnerInfo as a ON a.feeRef = x.feeRef AND a.feeBudRec = x.AvailableTime;
The problem is that I have no idea how to insert that subquery into the query I'm using to produce the report (as follows):
SELECT
uvw_EarnerInfo.feeRef
,uvw_EarnerInfo.PersonName
,uvw_EarnerInfo.PersonSurname
,uvw_EarnerInfo.feePin
,uvw_RB_TimeLedger.TimeDate
,uvw_RB_TimeLedger.matRef
,uvw_RB_TimeLedger.TimeTypeCode
,uvw_RB_TimeLedger.TimeCharge
,uvw_RB_TimeLedger.TimeElapsed
,uvw_WoffTimeByTime.WoffMins
,uvw_WoffTimeByTime.WoffCharge
,uvw_EarnerInfo.feeBudRec
,uvw_EarnerInfo.personOccupation
FROM
uvw_RB_TimeLedger
LEFT OUTER JOIN uvw_WoffTimeByTime
ON uvw_RB_TimeLedger.TimeId = uvw_WoffTimeByTime.TimeId
RIGHT OUTER JOIN uvw_EarnerInfo
ON uvw_EarnerInfo.feeRef = uvw_RB_TimeLedger.feeRef
WHERE
uvw_RB_TimeLedger.TimeDate >= #TimeDate
AND uvw_RB_TimeLedger.TimeDate <= #TimeDate2
If that subquery will get the correct results, can anyone please help me with inserting it into my report query. Otherwise, can anyone let me know what I will need to do to get a unique feeBudRec value for each feeRef?
Depends on the exact schema, but assuming the uvw_EarnerInfo lists the Pin, Ref, and Rec without duplicates, try adding an extra column (after personOccupation) on the end of your query such as :
feeBudRecSum = (Select SUM(FeeBudRec) From uvw_EarnerInfo x
where x.feePin = uvw_EarnerInfo.feePin
Group By x.FeePin)
Note that you would not Sum these values in your report. This column should have the total you are looking for.
The key to Report Builder is to get your query correct from the offset and let the wizard then structure your report for you. It takes all the hard work out of structuring your report manually.
I haven't used Report Builder for a while now but in the query builder of the report displaying the graphical representation of your query you should be able to drag and drop columns in and out of the query set. Dragging a column upwards and out of the box (showing your columns) would have the effect of causing your report to break on this column.
If you restructure this way you will probably have to run the report generator again to regenerate the report and restructure it.
Once you are happy with the structure you can then begin to add the summary columns.

SQL Server 2008 Query Result Formating (changing x and y axis fields)

What is the most efficient way to format query results, wether in the actual SQL Server SQL code or using a different program such as access or excel so that the X (first row column headers) and Y Axis (first column field values) can be changed, but with the same query result data still being represented, just in a different way.
they way the data is stored in my database and they way my original query results are returned in SQL Server 2008 are as follows:
Original Results Format
And Below is the way I need to have the data look:
How I need the Results to Look
In essence, I need to have the zipcode field go down the Y Axis (first column) and the Coveragecode field to go across the top first Row (X Axis) with the exposures filling in the rest of the data.
The only way I can thing of getting this done is by bringing the data into excel and doing a bunch of V-LookUps. I tried using some pivot tables but didn't get to far. I'm going to continue trying to format the data using the V-LookUps but hopefully someone can come up with a better way of doing this.
What you are looking for is a table operator called PIVOT. Docs: http://msdn.microsoft.com/en-us/library/ms177410.aspx
WITH Src AS(
SELECT Coveragecode, Zipcode, EarnedExposers
FROM yourTable
)
SELECT Zipcode, [BI], [PD], [PIP], [UMBI], [COMP], [COLL]
FROM Src
PIVOT(MAX(EarnedExposers) FOR CoverageCode
IN(
[BI],
[PD],
[PIP],
[UMBI],
[COMP],
[COLL]
)
) AS P;