Compute sum for distinct order numbers in ssrs report - sql-server

I'm using a SQL Server 2008R2 Database and SSRS Report Builder 3.0
Trying to compute the sum of the amount owed for each order id (need to show the itemids)...but when I do, the amount owed is showing 400 (instead of 200 - line 4, 100 instead of 50 in line 7, line 9 is correct. As a result the Total line is way off)
=Sum(Fields!owe.Value)
The report is grouped by the campus.
I understand that ssrs is probably not the best place to do this computation but I don't know how to do outside of ssrs....I tried distinct and group by so far with no results.
Below is how I need the report to show like....
Thanks in advance.
Incorrect amounts are
Another example as it should display the subtotals

I would modify the SQL to produce an extra column just for purposes of summing the Owe on an OrderId. Use the Row Number to get the first item in each order, and only supply the Owe value for that item for each order:
WITH cte AS (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY OrderId ORDER BY ItemId) AS rn
FROM MyTable
WHERE (whatever filters you use)
)
SELECT *,
CASE WHEN rn=1 THEN Owe ELSE 0 END AS OrderOwe
FROM cte
ORDER BY Campus, CustomerId, OrderId, ItemId
Then simply change the expression for the "Owe" textbox in your SubTotal row to this:
=Sum(Fields!OrderOwe.Value)
And you will get the sum of the Owe per order instead of per item.

Well if your owe is always the same for each item in the group you could add a Sum/Count of the item in the group which would give you the correct results in all the cases above.

Related

how to select first rows distinct by a column name in a sub-query in sql-server?

Actually I am building a Skype like tool wherein I have to show last 10 distinct users who have logged in my web application.
I have maintained a table in sql-server where there is one field called last_active_time. So, my requirement is to sort the table by last_active_time and show all the columns of last 10 distinct users.
There is another field called WWID which uniquely identifies a user.
I am able to find the distinct WWID but not able to select the all the columns of those rows.
I am using below query for finding the distinct wwid :
select distinct(wwid) from(select top 100 * from dbo.rvpvisitors where last_active_time!='' order by last_active_time DESC) as newView;
But how do I find those distinct rows. I want to show how much time they are away fromm web apps using the diff between curr time and last active time.
I am new to sql, may be the question is naive, but struggling to get it right.
If you are using proper data types for your columns you won't need a subquery to get that result, the following query should do the trick
SELECT TOP 10
[wwid]
,MAX([last_active_time]) AS [last_active_time]
FROM [dbo].[rvpvisitors]
WHERE
[last_active_time] != ''
GROUP BY
[wwid]
ORDER BY
[last_active_time] DESC
If the column [last_active_time] is of type varchar/nvarchar (which probably is the case since you check for empty strings in the WHERE statement) you might need to use CAST or CONVERT to treat it as an actual date, and be able to use function like MIN/MAX on it.
In general I would suggest you to use proper data types for your column, if you have dates or timestamps data use the "date" or "datetime2" data types
Edit:
The query aggregates the data based on the column [wwid], and for each returns the maximum [last_active_time].
The result is then sorted and filtered.
In order to add more columns "as-is" (without aggregating them) just add them in the SELECT and GROUP BY sections.
If you need more aggregated columns add them in the SELECT with the appropriate aggregation function (MIN/MAX/SUM/etc)
I suggest you have a look at GROUP BY on W3
To know more about the "execution order" of the instruction you can have a look here
You can solve problem like this by rank ordering the results by a key and finding the last x of those items, this removes duplicates while preserving the key order.
;
WITH RankOrdered AS
(
SELECT
*,
wwidRank = ROW_NUMBER() OVER (PARTITION BY wwid ORDER BY last_active_time DESC )
FROM
dbo.rvpvisitors
where
last_active_time!=''
)
SELECT TOP(10) * FROM RankOrdered WHERE wwidRank = 1
If my understanding is right, below query will give the desired output.
You can have conditions according to your need.
select top 10 distinct wwid from dbo.rvpvisitors order by last_active_time desc

SQL Error message: Column XXX is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause

SELECT
t.[Week], MAX(t.Revenue) AS 'Max Revenue'
FROM
(SELECT
[Week], SUM([Service Total]) AS Revenue
FROM
dbo.['Data - 2017 Appmt Time$']
GROUP BY
[Week]) t;
Error:
Column 't.Week' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
What I'm trying to do is to get the max revenue and the respective week for which is that max revenue. How to make that code working? The code is working if I don't select t.[Week] in the beginning but then I get only the max revenue. If I include t.[Week] in a group by clause, as the message suggests, that I have a list of all revenues week-by-week, but I don't need it. I only need the max revenue and for which week it is.
Apologies if my question is stupid, I'm a beginner in SQL and already lost much time searching for a solution. :( Thanks a lot in advance!
You cannot use a non aggregate column in select which is not part of Group By.
Actually you don't need derived table for this, to find the week with maximum revenue use TOP 1 with Order by
SELECT top 1 [Week],
Revenue = SUM([Service Total])
FROM dbo.['Data - 2017 Appmt Time$']
GROUP BY [Week]
order by Revenue desc
As mentioned by Dan Guzman, if there is a tie in maximum revenue and you want all the tie records then replace TOP 1 with TOP 1 with Ties

t sql sort by calculated column

I'm on T-SQL 2014 and try to order products by their price. Now here is the problem: the price is a calculated field. Eg. I have created a function which evaluates a number of pricing rules (maybe about 4 tables with each about 4,000,000 records combined with JOINs to fit to the current login) and returns the users price for the product. While this is OK if I just want to return the price for a limited number of products it is way to slow if I want to sort by this.
I was thinking about having an additional table like UserProductPrice which will get calculated in the background but this will obviously not always have the correct price in it as the rules etc. could change in between the calculation.
Any suggestion on how I could sort by the price would be most appreciated.
You could use the ROW_NUMBER() function and place this into a temp table:
SELECT
Product,
dbo.ufnPrice(Price) as Price,
ROW_NUMBER() OVER (PARTITION BY Product ORDER BY dbo.ufnPrice(Price) DESC) AS Ranking
INTO #Products
FROM dbo.Products
SELECT
Product,
Price,
FROM #Products
WHERE Ranking = 1
DROP TABLE #Products
Should give you what you need.

SQL Get Second Record

I am looking to retrieve only the second (duplicate) record from a data set. For example in the following picture:
Inside the UnitID column there is two separate records for 105. I only want the returned data set to return the second 105 record. Additionally, I want this query to return the second record for all duplicates, not just 105.
I have tried everything I can think of, albeit I am not that experience, and I cannot figure it out. Any help would be greatly appreciated.
You need to use GROUP BY for this.
Here's an example: (I can't read your first column name, so I'm calling it JobUnitK
SELECT MAX(JobUnitK), Unit
FROM JobUnits
WHERE DispatchDate = 'oct 4, 2015'
GROUP BY Unit
HAVING COUNT(*) > 1
I'm assuming JobUnitK is your ordering/id field. If it's not, just replace MAX(JobUnitK) with MAX(FieldIOrderWith).
Use RANK function. Rank the rows OVER PARTITION BY UnitId and pick the rows with rank 2 .
For reference -
https://msdn.microsoft.com/en-IN/library/ms176102.aspx
Assuming SQL Server 2005 and up, you can use the Row_Number windowing function:
WITH DupeCalc AS (
SELECT
DupID = Row_Number() OVER (PARTITION BY UnitID, ORDER BY JobUnitKeyID),
*
FROM JobUnits
WHERE DispatchDate = '20151004'
ORDER BY UnitID Desc
)
SELECT *
FROM DupeCalc
WHERE DupID >= 2
;
This is better than a solution that uses Max(JobUnitKeyID) for multiple reasons:
There could be more than one duplicate, in which case using Min(JobUnitKeyID) in conjunction with UnitID to join back on the UnitID where the JobUnitKeyID <> MinJobUnitKeyID` is required.
Except, using Min or Max requires you to join back to the same data (which will be inherently slower).
If the ordering key you use turns out to be non-unique, you won't be able to pull the right number of rows with either one.
If the ordering key consists of multiple columns, the query using Min or Max explodes in complexity.

Basic T-SQL COUNT

I'm new to T-SQL and this question is T-SQL Count 101.
I'm studying T-SQL with this site http://sqlmag.com/t-sql/t-sql-101-lesson-4 but I can't figure out Which part of coding says WHERE(column_name) to execute 'COUNT' if it makes sense? In other words, how does this COUNT know what to count? It just says COUNT everything as Reviews from MovieReview table.....
SELECT MovieName,
LEFT(REPLICATE('* ',AVG(Stars)),10)
AS 'Stars',
COUNT(*) AS 'Reviews'
FROM MovieReview
GROUP BY MovieName
HAVING COUNT(*) >= 4
ORDER BY Stars
Result:
The TABLE name is MovieReview that contains the ratings that the five employees have given to movies they’ve watched in their spare time. This table contains four columns: EmployeeID, Genre, MovieName, and Stars. The Stars field specifies the movie’s rating, where 1 star is the worst rating and 5 is the best rating.
I understand below coding because it specified WHERE. Count everything as '...' From Employee table Where salary is less than 3000.
SELECT COUNT(*)
AS 'Impoverished'
FROM Employee
WHERE Salary < 30000
I need to learn creating reports from Data Warehouse. I learned SQL but most of sites use T-SQL when creating reports, I don't know why.
Thanks in advance.
count(*) counts the number of rows that match the where clause if a where clause is given, per distinct combination of the group by columns if a group by column is given.
Except for the behavior noted in the previous sentence, count(*) ignores the values in those rows.

Resources