SSRS report arranging rows to columns - reporting-services

I need to generate this kind of (please see the image) report in SSRS, and I wrote below 2 SQL's
Active Appointments created by Online and Call center
Cancelled Appointments by Online and Call center
with cte as
(
select
ATS.[Description] as AppointmentSource, AST.AppointmentStatusName,
Month(A.Appointmentdate) as MonthNumber,
Count(A.AppointmentID) as NumberOfAppointments
from
Appointment A
inner join AppointmentStatus AST ON AST.AppointmentStatusID = A.AppointmentStatusID
inner join AppointmentSource ATS ON ATS.AppointmentSourceID = A.AppointmentSourceID
where A.AppointmentDate between '01/01/2020' and '12/31/2020'
AND ATS.AppointmentSourceID in (1,3)
AND A.AppointmentStatusID = 1 -- Active
Group by Month(A.AppointmentDate), ATS.[Description], AST.AppointmentStatusName
UNION
select
ATS.[Description] as AppointmentSource, AST.AppointmentStatusName, Month(A.Appointmentdate) as MonthNumber,
Count(A.AppointmentID) as NumberOfAppointments
from
Appointment A
inner join AppointmentStatus AST ON AST.AppointmentStatusID = A.AppointmentStatusID
inner join AppointmentSource ATS ON ATS.AppointmentSourceID = A.AppointmentSourceID
where A.AppointmentDate between '01/01/2020' and '12/31/2020'
AND ATS.AppointmentSourceID in (1,3)
AND A.AppointmentStatusID = 2 -- Cancelled
Group by Month(A.AppointmentDate), ATS.[Description], AST.AppointmentStatusName
)
select AppointmentSource, MonthNumber, NumberOfAppointments, AppointmentStatusName
from cte
order by AppointmentSource, AppointmentStatusName asc, MonthNumber
How to arrange the results by Month in the SSRS report ?
Is there a better way to write the SQL and arrange in SSRS report?

Ignoring the actual SQL for now (it would be better to show the results of this rather than the t-sql)...
I think you have enough to build the report, with the exception of the Year which you don't appear to be returning. Once you have corrected this...
Create a new report and create your dataset as normal
Add a Matrix (not a table) to your report.
Add 2 Row Groups first goruped by Year and the second (child group) grouped by AppointmentSource
Add a column group, grouped by MonthNumber
Choose NumberOfAppointments as the value
That's it, you should get the results as above more or less.

Related

MySQL Left Join throwing off my count numbers

I'm doing a left join on a table to get the number of leads we've generated today and how many times we've called those leads. I figured a left join would be the best thing to do, so I wrote the following query:
SELECT
COUNT(rad.phone_number) as lead_number, rals.lead_source_name as source, COUNT(racl.phone_number) as calls, SUM(case when racl.contacted = 1 then 1 else 0 end) as contacted
FROM reporting_app_data rad
LEFT JOIN reporting_app_call_logs racl ON rad.phone_number = racl.phone_number, reporting_app_lead_sources rals
WHERE DATE(rad.created_at) = CURDATE() AND rals.list_id = rad.lead_source
GROUP BY rad.lead_source;
But the problem with that, is that if in the reporting_app_call_logs table, there are multiple entries for the same phone number (so a phone number has been called multiple times that day), the lead_number (which I want to count how many leads were generated on the current day grouped by lead_source) equals how many calls there are. So the count from the LEFT table equals the count from the RIGHT table.
How do I write a SQL query that gets the number of leads and the total number of calls per lead source?
Try COUNT(DISTINCT expression)
In other words, change COUNT(rad.phone_number) to COUNT(DISTINCT rad.phone_number)

SSRS lookup with source not in current tablix

I have 3 tables that I want to show in a tablix SSRS report in 3.0.
Table 1 - policy ID, amt paid by company
Query - Select * from table1 where amt paid by company <> 0
Table 2 - policy ID, policy number, previous policy number
Query - Select * from table2 where previous policy number <> ' '
Table 3 - previous policy number, paid under prior company
Query - Select * from table3 where paid under prior company <> 0
I want to display the following columns on one tablix row per entry in table 1:
Policy number
amt paid by company
previous policy number
paid under prior company.
I created a tablix. I can display everything from table 1 and use lookup for table 2 items but when I do a lookup for item from table 3 it gives me an error.
From my research about this error I understand it to mean I cannot use the source in lookup from any table but table 1 in my case. And I can only do one level in lookup.
I have looked and can find no example for this anywhere and I have tried other methods and cannot figure out how to get to that piece of data in table 3.
Is my only choice to combine tables 2 and 3 together then use in this report with the lookup?
You can use INNER JOIN to get a dataset that contains all fields you require to show in the tablix.
SELECT
table2.PolicyNumber,
table1.AmntPaidByCompany,
table2.PrevPolicyNumber,
table3.PaidUnderPriorCompany
FROM table2
INNER JOIN table3
ON table2.PrevPolicyNumber = table3.PrevPolicyNumber
INNER JOIN table1
ON table1.PolicyID = table2.PolicyID
WHERE table1.AmntPaidByCompany <> 0
AND table2.PrevPolicyNumber <> ''
AND table3.PaidUnderPriorCompany <> 0
Live Demo
Let me know if this helps.

Build sql query from multiple tables for cyfe dashboard

For the purpose of monitoring my data from my users I want to visualise my data in a Cohort analysis. Lets say that i have the following tables in my database:
Table: track_register
user_id, date, time
And in the following table:
Table: track_loginuser_id, date, time, succes
How i want my cohort analysis to look is like:
Months Sign Ups loged in more then once
May 40 80%
I am using Cyfe to visualise this so the data has to be formatted in a table like this:
Month,Sign Ups,Loged in more then once
May 2015,40,32
Jun 2015,60,55
(click here for cyfe example)
Eventually i want to add more data to the cohort from other tables such as percentage of users who actually bought the product and more of that good stuff.
The first set of data (the signups per month) is not the hard part. But what i am struggling with is how to fetch the data from the track login table. I will have to count the number of times a specific user has loged in and if thats > 1 then +1. I can imagine that u use CASE for that. The trouble is to separated it by the correct moth. Because the moth where de +1 supposed to go needs to be fetched from the track_register table.
Its seems kind of hard to me to put this all in one single query? But if it couldn't be done why go to the trouble of building a cohort analysis on cyfe?
Hi DATE as field name is restricted so I used DATA.
You can try this code:
SELECT TO_CHAR(NVL(a.data, b.data), 'MON YYYY') months
, COUNT(DISTINCT a.login) sign_ups
, SUM(CASE WHEN COUNT(DISTINCT b.login) > 1 THEN 1 ELSE 0 END) Loged_in_more_then_once
FROM track_register a LEFT JOIN track_login b ON a.login = b.login
GROUP BY TO_CHAR(NVL(a.data, b.data), 'MON YYYY')
ORDER BY 1
Or:
SELECT TO_CHAR(NVL(a.data, b.data), 'MON YYYY') months
, COUNT(DISTINCT a.login) sign_ups
, SUM(CASE WHEN COUNT(DISTINCT b.login) > 1 THEN 1 ELSE 0 END) Loged_in_more_then_once
FROM track_register a LEFT JOIN track_login b
ON a.login = b.login AND LAST_DAY(a.data) = LAST_DAY(b.data)
GROUP BY TO_CHAR(NVL(a.data, b.data), 'MON YYYY')
ORDER BY 1

Complex SQL Select query with inner join

My SQL query needs to return a list of values alongside the date, but with my limited knowledge I have only been able to get this far.
This is my SQL:
select lsu_students.student_grouping,lsu_attendance.class_date,
count(lsu_attendance.attendance_status) AS count
from lsu_attendance
inner join lsu_students
ON lsu_students.student_grouping="Central1A"
and lsu_students.student_id=lsu_attendance.student_id
where lsu_attendance.attendance_status="Present"
and lsu_attendance.class_date="2015-02-09";
This returns:
student_grouping class_date count
Central1A 2015-02-09 23
I want it to return:
student_grouping class_date count
Central1A 2015-02-09 23
Central1A 2015-02-10 11
Central1A 2015-02-11 21
Central1A 2015-02-12 25
This query gets the list of the dates according to the student grouping:
select distinct(class_date)from lsu_attendance,lsu_students
where lsu_students.student_grouping like "Central1A"
and lsu_students.student_id = lsu_attendance.student_id
order by class_date
I think you just want a group by:
select s.student_grouping, a.class_date, count(a.attendance_status) AS count
from lsu_attendance a inner join
lsu_students s
ON s.student_grouping = 'Central1A' and
s.student_id = a.student_id
where a.attendance_status = 'Present'
group by s.student_grouping, a.class_date;
Comments:
Using single quotes for string constants, unless you have a good reason.
If you want a range of class dates, then use a where with appropriate filtering logic.
Notice the table aliases. The query is easier to write and to read.
I added student grouping to the group by. This would be required by any SQL engine other than MySQL.
Just take out and lsu_attendance.class_date="2015-02-09" or change it to a range, and then add (at the end) GROUP BY lsu_students.student_grouping,lsu_attendance.class_date.
The group by clause is what you're looking for, to limit aggregates (e.g. the count function) to work within each group.
To get the number of students present in each group on each date, you would do something like this:
select student_grouping, class_date, count(*) as present_count
from lsu_students join lsu_attendance using (student_id)
where attendance_status = 'Present'
group by student_grouping, class_date
Note: for your example, using is simpler than on (if your SQL supports it), and putting the table name before each field name isn't necessary if the column name doesn't appear in more than one table (though it doesn't hurt).
If you want to limit which data rows get included, put your constraints get in the where clause (this constrains which rows are counted). If you want to constrain the aggregate values that are displayed, you have to use the having clause. For example, to see the count of Central1A students present each day, but only display those dates where more than 20 students showed up:
select student_grouping, class_date, count(*) as present_count
from lsu_students join lsu_attendance using (student_id)
where attendance_status = 'Present' and student_grouping = 'Central1A'
group by student_grouping, class_date
having count(*) > 20

N or more continuous year range

I have to create a report using MySql DB where more than 4 tables are involved. I have one table (S1) with S1_ID and S1_Year_Range (strings like 2001-2002) and another table (S2) with S2_ID(PK), S2_Customer_ID, S1_ID (FK) and other fields for other conditions that can appear in Where clause of my query. There can be more than one row in S2 with the same S2_Customer_ID but different S1_ID. My query is to create a report using VB.net and ask users to enter two values; one number for how many continuous years or bigger (like >= 5 years), and a year range value (like 2011-2012) which is the highest value in the list for all customers.
My report lists customer names (by joining the above query with another table), customer rank and all year range values (highest at the bottom) for that customer in one column for each customer. Any help for this query would be appreciated.
Data and results could be like the following:
S1:
(S1_ID....S1_Year_Range)
(1......2000-2001)
(2......2001-2002)
(3......2002-2003)
(4......2003-2004)
(5......2004-2005)
etc
S2:
(S2_ID.....S2_Customer_ID.....S1_ID)
(1....1....1)
(2....1....2)
(3....1....3)
(4....2....2)
(5....2....3)
(6....2....5)
(7....3....2)
(8....3....3)
(9....3....4)
(10...3....5)
(11...4....3)
(12...4....4)
(13...4....5)
etc
when number 2 and year range (2003-2004) is entered by the user, the result should be the following:
customer 3 with 3 year range values (2003-2004, 2002-2003, and 2001-2002) and customer 4 with 2 year range values (2003-2004 and 2002-2003):
cname3
2001-2002
2002-2003
2003-2004
cname4
2002-2003
2003-2004
I hope you can see the columns of the report correctly.
I finally created a complex query to solve my problem. In the following query, I encoded the user year range value as '2010-2011' and number of continuous years as 14. Also a tiny difference with the question is the table names; table CSP here is the same as table S2 in my question but field names are the same as those in my question.
SELECT CSYWFY.S2_Customer_ID, COUNT(CSYWFY.S2_Customer_ID)
FROM (SELECT S1F.S1_Year_Range, S2.S2_Customer_ID , COUNT(S1F.S1_Year_Range) FROM CSP as S2 INNER JOIN S1 as S1F ON S2.S1_ID = S1F.S1_ID WHERE '2010-2011' IN (SELECT S1N.S1_Year_Range FROM CSP as S2N INNER JOIN S1 as S1N ON S2N.S1_ID = S1N.S1_ID WHERE S2N.S2_Customer_ID = S2.S2_Customer_ID ) GROUP BY S2.S2_Customer_ID ASC , S1F.S1_Year_Range DESC ) CSYWFY
GROUP BY CSYWFY.S2_Customer_ID
HAVING COUNT(CSYWFY.S2_Customer_ID) > 14
HTH