divide two table value in SSRS - sql

I´ve got two tables in my Report:
I would like to divide the value from Scrap with the value from Table Total
--> (16227 / 425841) * 100
This is the code:
Select date as Datetime, tevent.name as Event, SUM(value) as sum
from tCount inner join tEvent ON tCount.eventid = tevent.id
where Name in ('Drive Fast', 'Drive Slow')
and date > getdate() -1
and tevent.Name in ('E01','E02','E03','E04','E05','E06','E07','E08')
and CalName = 'Drive'
The sum of these: 'E01','E02','E03','E04','E05','E06','E07','E08', I did it in the report like this: Sum(Fields!E01.Value+Fields!E02.Value+Fields!E03.Value+...
And for the other table it looks like this:
Select date as Datetime, tevent.name as Event, SUM(value) as sum
from tCount inner join tEvent ON tCount.eventid = tevent.id
where Name in ('Drive Normal')
and date > getdate() -1
and tevent.Name in ('E01','E02','E03','E04','E05','E06','E07','E08')
and CalName = 'Drive'
And I must do a division of this two statements.
But if I put in the Scrap Expression the value from Total then the result is wrong. Hope you can help me.

From what I understand of your question, you have two datasets, and you want to calculate the percentage of Scrap of the Total
To replicate your problem I have created two DataSets as follows
Scrap Dataset
myDateTime Event mySum
01/01/2015 Scrap 16227
02/01/2015 Scrap 14637
03/01/2015 Scrap 14174
Total Dataset
myDateTime Event mySum
01/01/2015 Total 425841
02/01/2015 Total 434024
03/01/2015 Total 405216
Create a Table in your report and set column 1 to be mySum from ScrapDataSet
Then you can use the LOOKUP function in Column 2 to look up a specific value from another dataset assuming there is a common field. In this instance
=Lookup(Fields!myDateTime.Value,
Fields!myDateTime.Value,
Fields!mySum.Value,
"TotalDataSet")
Compares myDateTime in ScrapDataSet to myDateTime in TotalDataSet, and where there is a match returns mySum from TotalDataSet
You can then combine these two expressions as follows to get the percentage as required in Column 3
=Fields!mySum.Value /
(Lookup(Fields!myDateTime.Value,
Fields!myDateTime.Value,
Fields!mySum.Value,
"TotalDataSet"))
In this example I formatted this third column to be a percentage format to 2 decimal places.
These steps result in a table that looks like this
Hopefully this is the output you require. If you need further assistance please ask with clarification of the original question.
As a final note Sum and DateTime are not recommended field names as these are both keywords that can be used in SSRS to either define a type of perform a function. These should really be renamed – as I have done in the example above.

Related

Calculate stdev over a variable range in SQL Server

Table format is as follows:
Date ID subID value
-----------------------------
7/1/1996 100 1 .0543
7/1/1996 100 2 .0023
7/1/1996 200 1 -.0410
8/1/1996 100 1 -.0230
8/1/1996 200 1 .0121
I'd like to apply STDEV to the value column where date falls within a specified range, grouping on the ID column.
Desired output would like something like this:
DateRange, ID, std_v
1 100 .0232
2 100 .0323
1 200 .0423
One idea I've had that works but is clunky, involves creating an additional column (which I've called 'partition') to identify a 'group' of values over which STDEV is taken (by using the OVER function and PARTITION BY applied to 'partition' and 'ID' variables).
Creating the partition variable involves a CASE statement prior where a given record is assigned a partition based on its date falling within a given range (ie,
...
, partition = CASE
WHEN date BETWEEN '7/1/1996' AND '10/1/1996' THEN 1
WHEN date BETWEEN '10/1/1996' AND '1/1/1997' THEN 2
...
Ideally, I'd be able to apply STDEV and the OVER function partitioning on the variable ID and variable date ranges (eg, say, trailing 3 months for a given reference date). Once this works for the 3 month period described above, I'd like to be able to make the date range variable, creating an additional '#dateRange' variable at the start of the program to be able to run this for 2, 3, 6, etc month ranges.
I ended up coming upon a solution to my question.
You can join the original table to a second table, consisting of a unique list of the dates in the first table, applying a BETWEEN clause to specify desired range.
Sample query below.
Initial table, with columns (#excessRets):
Date, ID, subID, value
Second table, a unique list of dates in the previous, with columns (#dates):
Date
select d.date, er.id, STDEV(er.value)
from #dates d
inner join #excessRet er
on er.date between DATEADD(m, -36, d.date) and d.date
group by d.date, er.id
order by er.id, d.date
To achieve the desired next step referenced above (making range variable), simply create a variable at the outset and replace "36" with the variable.

SQL minimum date value after today's date Now()

I am writing a query and am having trouble filtering data as I would like. In the table, there is a date field and an ItemCode field. I would like to return one record per ItemCode with the earliest date that is after today.
If today is 6/6/2017 and my data looks like:
ItemCode Date
1 6/1/2017
1 6/7/2017
1 6/10/2017
2 6/2/2017
2 6/8/2017
2 6/15/2017
I would want the result to be
ItemCode Date
1 6/7/2017
2 6/8/2017
My query so far is:
SELECT PO_PurchaseOrderDetail.ItemCode, Min(PO_PurchaseOrderDetail.RequiredDate) AS NextPO
FROM PO_PurchaseOrderDetail
GROUP BY PO_PurchaseOrderDetail.ItemCode
HAVING (((Min(PO_PurchaseOrderDetail.RequiredDate))>=Now()));
The problem is that the Min function fires first and grabs the earliest dates per ItemCode, which are before today. Then the >=Now() is evaluated and because the min dates are before today, the query returns nothing.
I've tried putting the >=Now() inside the min function in the HAVING part of the query but it does not change the result.
My structure is wrong and I would appreciate any advice. Thanks!
I would approach like this for standard SQL, Access approach may vary
select PO_PurchaseOrderDetail.ItemCode,
min(PO_PurchaseOrderDetail.RequiredDate) as NextPO
from PO_PurchaseOrderDetail
where PO_PurchaseOrderDetail.RequiredDate >= Now()
group by PO_PurchaseOrderDetail.ItemCode;
Put the date condition in the where clause (not the having clause):
select ItemCode, min(Date) as NextPO
from PO_PurchaseOrderDetail
where Date > '6/6/2017'
group by ItemCode

SQL: select datetime values prior to that date based on it's value

I want to select rows for a field MRD which is declared as date where it is prior for that date only.
So
(case when sum (transPoints) > 4 and MRD is that same date then 4
So if a row has a date of today, I want the case when to be triggered when the transaction points are bigger than 4 against all columns with the same date.
As you can imagine the date field will be different against many rows.
Based on what I can understand from your question, it seems that the GROUP BY clause may be what you're looking for. If your date column is in the correct format then you may have to use something like:
SELECT CAST(DateColumn as DATE)
FROM YourTable
GROUP BY CAST(DateColumn as DATE)

IN Clause issue

I have one SQL output table like this
ITEM,LOC,PERIOD,QUANTITY
101,US,07/22/2015,500
101,US,07/02/2015,0
102,LON,07/22/2015,0
102,LON,07/02/2015,1000
But I want the output table as follows,
ITEM LOC 07/22/2015 07/02/2015
101 US 500 0
102 LON 0 1000
Please find the code which I have used below,
select * from
(
select item, loc, period, quantity
from example
)
pivot
(
sum (quantity) for period in ('22/JUL/2015','02/JUL/2015'));
If it is for 2 dates, then no issue in mentionning the 'IN' clause
If it is 1000 dates like weekly, monthly and daily. Then how ?
Below command is not working in 'IN' clause.
SELECT PERIOD FROM EXAMPLE WHERE PERIOD < TO_DATE(22/JUL/2015);
Can you please help me to solve this issue ?
Thanks for your time.
Your issue may be incompatible data types. If the period column on your table is DATE type, you are trying to compare strings/VARCHAR with DATE type.
If period column is a DATE try changing your IN to
SELECT period FROM example WHERE period < DATE '2015-07-22';
or
SELECT period FROM example WHERE period < TO_DATE('22/JUL/2015', 'DD/MON/YYYY');

Adjust date column for change over time

This is an easy enough problem, but wondering if anyone can provide a more elegant solution.
I've got a table that consists of a date column (month end dates over time) and several value columns--say the price on a variety of stocks over time, one column for each stock. I'd like to calculate the change in value columns for each period represented in the date column (eg, a daily return from a table filled with prices).
My current plan is to join the table to itself and simply create a new column for the return as ret = b.price/a.price - 1. Code as follows:
select Date, Ret = (b.stock1/a.stock1 - 1)
from #temp a, #temp b
where datediff(day, a.Date,b.Date) between 25 and 35
order by a.Date
This works fine, BUT:
(1) I need to do this for, say, dozens of stocks--is there a good way to replicate the calculation without copying and pasting the return calculation and replacing 'stock1' with each other stock name?
(2) Is there a better way to do this join? I'm effectively doing a cross join at this point and only keeping entries that are adjacent (as defined by the datediff and range), but wondering if there's a better way to join a table like this to itself.
EDIT: Per request, data is in the form (my data has multiple price columns though):
Date Price
7/1/1996 349.22
7/31/1996 337.72
8/30/1996 343.70
9/30/1996 357.23
10/31/1996 364.07
11/29/1996 385.04
12/31/1996 383.68
And from that, I'd like to calculate return, to generate a table like this (again, with additional columns for the extra price columns that exist in the actual table):
Date Ret
7/31/1996 -0.03
8/30/1996 0.02
9/30/1996 0.04
10/31/1996 0.02
11/29/1996 0.06
12/31/1996 0.00
I would do the following. First, use the month and year to do the self join. I woudl recommend you take the year * 12 + the month number to get a unique value for each month and year combination. So, Jan of 2011 would have a value of (2011 * 12 + 1 = 24133) and December of 2010 would have a value of (2010 * 12 + 12 = 24132). This will allow you to accurately compare months without having to mess with rolling over from December to January. Next, you need to supply the calculations in the select clause. If you have the stock values in different columns then you will have to type them out as a.stock1-b.stock1, a.stock2-b.stock2, etc. The only way around that would be to massage the data to where there is only one stock value column and add a stockname column that would identify what stock that value is for.
Using the Month and Year for the self join, the following query should work:
select Date, Ret = (b.stock1/a.stock1 - 1)
from #temp a
inner join #temp b on (YEAR(a.Date) * 12) + MONTH(a.Date) = (YEAR(b.Date) * 12) + MONTH(b.Date) + 1
order by a.Date