SSRS multi axis chart issue - sql-server

I was wondering if anyone can help me with this issue I have been having for at least a good 10 hours now after playing with it. I am going to use the Movies database from wiseowl to illustrate this instead.
I have the following SQL:
SELECT FilmReleaseDate
,FilmName
,directorname
,FilmRunTimeMinutes
,directorgender
,CountryName
,datename(M, FilmReleaseDate) AS [month]
,month(FilmReleaseDate) AS [month_no]
,year(FilmReleaseDate) AS [Year]
FROM tblFilm
INNER JOIN tblDirector ON directorID = FilmDirectorID
INNER JOIN tblCountry ON FilmCountryID = CountryID
WHERE FilmReleaseDate >= '2006-01-01'
now say I want to put this into a stacked chart with the movies from each country, the second axis will show the running minutes of the films. But the problem here is that I want the average for all countries, not for each one. Is there any way to do this so I have 1 line rather then 3 lines.
here is how the out put looks like
as you can see from output there are 3 lines for the 3 countries in the result, is there a way to get an average for all of them in one line rather then each one so the output will have only one line showing the average.
If anyone can help I will really appreciate it as I have spent countless hours on this. Any other info you need let me know.

Try this script. Then use the new field D.AVGFilmRunTimeMinutes on your chart. I added aliases on each table on the script. Just correct the aliases if they're pointing to a wrong table.
SELECT A.FilmReleaseDate
,A.FilmName
,B.directorname
,D.AVGFilmRunTimeMinutes
,B.directorgender
,C.CountryName
,datename(M, A.FilmReleaseDate) AS [month]
,month(A.FilmReleaseDate) AS [month_no]
,year(A.FilmReleaseDate) AS [Year]
FROM tblFilm A
INNER JOIN tblDirector B ON directorID = A.FilmDirectorID
INNER JOIN tblCountry C ON A.FilmCountryID = B.CountryID
LEFT JOIN (SELECT AVG(FilmRunTimeMinutes) AS AVGFilmRunTimeMinutes,FilmDirectorID FROM tblFilm GROUP BY FilmDirectorID) D
ON D.FilmDirectorID = A.FilmDirectorID
WHERE A.FilmReleaseDate >= '2006-01-01'

The reason your chart is producing 3 lines instead of one, is due to the grouping in you chart for each month (determined by how many countries).
I don't know the structure of your table, so I would recommend adding another field to your dataset:
YEAR(A.FilmReleaseDate) * 100 + MONTH(A.FilmReleaseDate) AS [YearMonth]
This will add a field with the format YYYYMM
Add this to your chart on your axis instead year and month_no.
In the Chart Data window, click the drop down next to the newly created Category Group for Year Month. Select Chart Group Properties, and copy the name. (It should be called something like - Chart1_CategoryGroup)
The final step is to modify the expression for your Film Run Time in the chart.
Click on the drop down next to FilmRunTimeMinutes, and click Series Properties.
In the value field use the following:
=Avg(Fields!FilmRunTimeMinutes.Value,"Chart1_CategoryGroup1")
Replacing Chart1_CategoryGroup1 with what your Category Group is called.

Related

Can I use Dimension table ‘startdate’ instead Fact table?

I’m joining dim table & fact table with start date. Can I use start date from dim table instead fact? If so why we need to use fact table start date? Below is the example:
Select count(*)
from dim_table d
Inner join fact_table f
On d.bizkeys = f.bizkeys
Where currentind =‘1’
And d.startdate = (select max(startdate) from dim_table)
After giving startdate condition I’m getting 1.8 million records, if I give
f.startdate = (select max(startdate) from fact_table)
I got 100 million records.
Can anyone Please clarify my doubt? Why I’m seeing this huge variation?
If you're just trying to get a list of all possible dates from the dimension (say, for a dropdown in your reporting tool that would let the user pick a date), then there's probably no reason that you would join to the fact table—unless you only want to include dates for which there's a corresponding fact record.
Without some sample data (or at least a little more information about the substance of the fact and dimension tables), I'm not sure I can give a better answer than that.

Find the Min and Max date from two tables from a sql select statement

Cant seem to wrap my head round this problem.
I have two tables one which has the following sample values:
Second table had the following values:
What i am trying to achieve is like the following:
So you can see the first table has the modules, what year and what term.
Based on these there is a start week and and end week.
The lookup table for the start and the finish unfortunatley is in a week basis and i need the begin week to match the second tables weekNo based on the season i guess and taking the start date being Sdate from that table to match what i am looking for and then the same applies to the end date.
Match the season and the endweek with the second tables WeekNo and Edate and only bring that date in.
Hope i made a bit of sense but i am hoping the third image shows what i am look for.
I've tried CTE, Group by, Partition by, order by, min, max and got nowhere :(
Dont really want to hard code anything, so was hoping you wonderful peps can help me out !!
Many thanks in advance :)
I suspect you are trying to achieve this by using one a single join between the tables - whereas what you actually need is two separate joins:
SELECT table1.module as mod_code,
table1.season as psl_code,
table2.Sdate as ypd_sdate,
table3.Edate as ypd_edate
FROM t1 as table1
JOIN t2 as table2 ON table2.yr = table1.year AND table2.season = table1.season AND table2.weekNo = table1.BeginWeek
JOIN t2 as table3 ON table3.yr = table1.year AND table3.season = table1.season AND table3.weekNo = table1.EndWeek

How to Correct This SQL CODE?

This is the question using AdvetureWorks2012.
Create a VIEW dbo.vw_Commissions to display the commissions earned last
year by all sales employees. Round the result set to two decimal places and do not include any salesperson who did not earn a commission. Include the
salesperson name, the commission earned, and the job title. Concatenate the
salesperson first and last names.
This code is not working for me. What am I screwing up?
USE AdventureWorks2012
GO
CREATE VIEW dbo.vw_Commissions
AS
SELECT
Sales.SalesPerson.SalesLastYear,
Person.Person.LastName,
Person.Person.FirstName,
HumanResources.Employee.JobTitle
FROM
Sales.SalesPerson
LEFT OUTER JOIN
Sales.SalesPerson ON Sales.SalesPerson.BusinessEntityID = Person.Person.BusinessEntityID
LEFT OUTER JOIN
Person.Person ON Person.Person.BusinessEntityID = HumanResources.Employee.BusinessEntityID
There are multiple problems with your query.
The biggest problem is it is not answering the questions asked. You are selecting SalesLastYear whereas the question asks to calculate the Commissions.
You are not filtering SalesPersons which have not earned any commission.
You need this to run only for last year.
Concatenate the FirstName and LastName.
The error you are getting is because you are using Sales.SalesPerson twice in your query. You need to give them alias names. However, I don't think you need two instances of the same table in this query. Also to use HumanResources.Employee.JobTitle column in the select list, you need to include table HumanResources.Employee in the from list.

SQL Server - Count the number of times the contents of a specified field repeat in a table

What's the best way to 'SELECT' a 'DISTINCT' list of a field from a table / view (with 'WHERE' criteria) and alongside that count the number of times that that field content repeats in the table / view?
In other words, I have an initial view that looks a bit like this:
I'd like a single SQL query to filter it (SELECT...WHERE...) so that we are only considering records where [ORDER COMPLETE] = False and [PERSONAL] = Null...
...and then create a distinct list of names with counts of the number of times each name appears in the previous table:
*Displaying the [ORDER COMPLETE] and [PERSONAL] fields is redundant by this point and could be dropped to simplify.
I can do the steps individually as above, but struggling to get a single query to do it all... any help appreciated!
Thanks in advance,
-Tim
This should just be the following
SELECT dbo.tblPerson.Person,
COUNT(dbo.tblPerson.Person) AS Count
FROM dbo.tblPerson
INNER JOIN dbo.tblNotifications ON dbo.tblPerson.PersonID = dbo.tblNotifications.AddresseeID
WHERE dbo.tblNotifications.Complete = 'False'
AND dbo.tblNotifications.Personal IS NULL
GROUP BY dbo.tblPerson.Person
ORDER BY COUNT(dbo.tblPerson.Person) DESC
You don't need your DISTINCT or TOP 100 PERCENT,
Here is a simplified fiddle
Well I got downvoted into oblivion (probably for displaying the full extent of my own ignorance!), but just in case someone from the future experiences the same problem as me and stumbles across this question while Googling (or whatever verb you use for "searching all digitised human knowledge" in the distant future), here's some sanitised code of the query I managed to get to work in the end - thanks to Mark Sinkinson's snippet for helping me realise the obvious...
SELECT DISTINCT TOP (100) PERCENT dbo.tblPerson.Person, COUNT(dbo.tblPerson.Person) AS CountPerson
FROM dbo.tblPerson INNER JOIN
dbo.tblNotifications ON dbo.tblPerson.PersonID = dbo.tblNotifications.AddresseeID
WHERE (dbo.tblNotifications.Complete = 'False') AND (dbo.tblNotifications.Personal IS NULL)
GROUP BY dbo.tblPerson.Person
ORDER BY CountPerson DESC

Multi join issue

*EDIT** Thanks for all the input, and sorry for late reply. I have been away during the weekend without access to internet. I realized from the answers that I needed to provide more information, so people could understand the problem more throughly so here it comes:
I am migrating an old database design to a new design. The old one is a mess and very confusing ( I haven't been involved in the old design ). I've attached a picture of the relevent part of the old design below:
The table called Item will exist in the new design as well, and it got all columns that I need in the new design as well except one and it is here my problem begin. I need the column which I named 'neededProp' to be associated( with associated I mean like a column in the new Item table in the new design) with each new migrated row from Item.
So for a particular eid in table Environment there can be n entries in table Item. The "corresponding" set exists in table Room. The only way to know which rows that are associated in Item and Room are with the help of the columns "itemId" and "objectId" in the respective table. So for example for a particular eid there might be 100 entries in Item and Room and their "itemId" and "objectId" can be values from 1 to 100, so that column is only unique for a particular eid ( or baseSeq which it is called in table BaseFile).
Basically you can say that the tables Environment and BaseFile reminds of each other and the tables Item and Room reminds of each other. The difference is that some tables lack some columns and other may have some extra. I have no idea why it is designed like this from the beginning.
My question is if someone can help me with creating a query so that I can be able to find out the proper "neededProp" for each row in the Item-table so I can get that data into the new design?
*OLD-PART**This might be a trivial question but I can't get it to work as I want. I want to join a few tables as in the sql-statement below. If I start like this and run this query
select * from Environment e
join items ei on e.eid = ei.eid
I get like 400000 rows which is what I want. However if I add one more line so it looks like this:
select * from Environment e
join items ei on e.eid= ei.eid
left join Room r on e.roomnr = r.roomobjectnr
I get an insane amount of rows so there must be some multiplication going on. I want to get the same amount of rows ( like 400000 in this case ) even after joining the third table. Is that possible somehow? Maybe like creating a temporary view with the first 2 rows.
I am using MSSQL server.
So without knowing what data you have in your second query it's very difficult to say exactly how to write this out, and you're likely having a problem where there's an additional column that you are joining to in Rooms that perhaps you have forgotten such as something indicating a facility or hallway perhaps where you have multiple 'Room 1' entries as an example.
However, to answer your question regarding another way to write this out without using a temp table I've crufted up the below as an example of using a common table expression which will only return one record per source row.
;WITH cte_EnvironmentItems AS (
SELECT *
FROM Environment E
INNER JOIN Items I ON I.eid = E.eid
), cte_RankedRoom AS (
SELECT *
,ROW_NUMBER() OVER (ORDER BY R.UpdateDate DESC) [RN]
FROM Room R
)
SELECT *
FROM cte_EnvironmentItems E
LEFT JOIN cte_RankedRoom R ON E.roomnr = R.roomobjectnr
AND R.RN = 1
btw,do you want column from room table.if no then
select * from Environment e
join items ei on e.eid= ei.eid
where e.roomnr in (select r.roomobjectnr from Room r )
else
select * from Environment e
join items ei on e.eid= ei.eid
left join (select distinct roomobjectnr from Room) r on e.roomnr = r.roomobjectnr

Resources