SSRS/T-SQL sum if another condition is met - sql

Basically I have an application that processes transactions. Each transaction has a transaction number. In the application view on the front the total for each transaction is calculated but it is not stored in the database (and this cannot be changed)
Now in SSRS they want to see the value come through on the report. The way to do this is to match the transaction number and if they match (no matter how many records) it adds them up on is there a way to do this on SSRS? Or maybe a more elegant way to do it would be to do it in the stored procedure.
And example of this is below which I know won't work but just to give you an idea of what I'm trying to accomplish here:
SELECT transactionID
, value
, Sum(Case When transactionID = TransactionID Then Value Else 0) As Total
EDIT: In response to some of the comments I made this edit. First off in the above I made a mistake and did TransactionID = transaction but it should be what it is currently.
Continuing on... In order to do this I need to match the transaction number against other transaction numbers in the data set and see if there is a match. To illustrate I did this example below:
This is an example dataset:
TransId: 1 Value: 200
TransId: 2 Value: 300
TransId: 1 Value: 100
TransId: 2 Value: 500
TransId: 1 Value: 400
From this dataset I should get these values in the report:
TransId: 1 Value: 200 Total: 700
TransId: 2 Value: 300 Total: 800
TransId: 1 Value: 100 Total: 700
TransId: 2 Value: 500 Total: 800
TransId: 1 Value: 400 Total: 700
So for each row I want to see the complete total for each record(TransID) and not a runnign total.

Window functions are just so much more fun though:
SELECT TransactionId
, Value
, SUM(Value) OVER(PARTITION BY TransactionId) AS Total
FROM SomeTable
SQL Fiddle

This should do the trick
select transactionID
, value
, TransactionSum
from MyTable t
join (select transactionID
, sum (value) as TransactionSum
from MyTable
group by transactionID
) x on t.transactionID = x.transactionID

Just another way of doing it
select a.transid,
a.value,
(select sum(b.value) from yourTable b where b.transid = a.transid) as Total
from yourTable a

Related

I need a support for sql query

I have a table with 3 columns lower range,upper range, discount amount
I am passing a number and finding in which range it belongs to and retrieving its discount amount
But i am passing a number that not in this table in this case i need the last range discount amount from table
I need a sql query for the same
0-10 100
11-20 200
21-30 300
if i am passing 5 need to get 100
if i am passing 15 200 as result
but if i am passing 50 i need to get 300 as result
Ie. If the value that is passing not in the range need to get the highest ranges discount amount.
Plzz help. Mee
Try this. You can directly pass/use #value in the script as well.
DECLARE #Value INT
SET #Value = 35
SELECT SUM(DISCOUNT) Discount
FROM
(
SELECT
CASE
WHEN upper_range = (SELECT MAX(upper_range) FROM your_table) AND #Value > upper_range THEN DISCOUNT
WHEN #Value BETWEEN lower_range AND upper_range THEN DISCOUNT
ELSE 0
END
DISCOUNT
FROM your_table
) A
Output for value 35 is-
300
With UNION ALL:
select discount
from tablename
where x between lowerrange and upperrange
union all
select max(discount) from tablename
where not exists (
select 1 from tablename
where x between lowerrange and upperrange
)
If the 1st query does not return a result, then the value will be fetched by the 2nd query.
If the 1st query returns a result, then the 2nd will not return anything.
Applies to any major rdbms.

SQL less than specific value between two columns

I'm trying to make a statement to compare a specific value of '300' between the following two columns:
m02_bal_amount
m01_bal_amount
How would I state that specific value between the two columns I would like to be less than?
i.e between the two columns listed above how can filter to show a difference of 300.
m02 m01
15 400
0 300
90 1000
SELECT * FROM Database where data_pool = 0 and db_load_dt = '2012-01-10' and m02_bal_amount <= m01_bal_amount for fetch only with ur
Thanks very much
Try BETWEEN
SELECT * FROM Database where data_pool = 0 and db_load_dt = '2012-01-10'
AND amount BETWEEN m02_bal_amount AND m01_bal_amount
I do't know your table schema. Try something like this
Update:
SELECT id, name, amount FROM
(
SELECT id, name, (m02_bal_amount - m01_bal_amount ) AS amount
WHERE
data_pool = 0 and
db_load_dt = '2012-01-10'
)
AS temp
WHERE amount > 300

Find the proportion of rows verifying a condition in a single SQL query

Suppose I have a sales table which is as follows:
ID | Price
----------------------
1 0.33
2 1.5
3 0.5
4 10
5 0.99
I would like to find, in a single query, the proportion of rows verifying a given condition. For example, if the condition is Price < 1, the result should be 3/5 = 0.6.
The only workaround that I have found so far is :
SELECT
SUM(
CASE
WHEN Price < 1
THEN 1
WHEN Price >= 1
THEN 0
END
)/COUNT(*)
FROM sales
but is there a way to do this without CASE ?
You can do it with IF:
SELECT SUM(IF(Price < 1, 1, 0))/COUNT(*) FROM sales
-but it's no big difference from CASE (your logic here is correct)
You may want to use WHERE (to sum only Price<1) - but since you're using total COUNT it's not valid in your case. Another option: get total count separately:
SELECT
COUNT(sales.Price)/total_count
FROM
sales
CROSS JOIN (SELECT COUNt(*) AS total_count FROM sales) AS c
WHERE
-- you're summing 1 or 0 depending of Price, so your sum is
-- just count where Price<1
sales.Price<1

MS Access query table without primary key

Claim# Total ValuationDt
1 100 1/1/12
2 550 1/1/12
1 2000 3/1/12
2 100 4/1/12
1 2100 8/1/12
3 200 8/1/12
3 250 11/1/12
Using MS Access, I need a query that returns only claims which have been valuated greater than $500 at some point in that claim's life time. In this example, the query should return
Claim# Total ValuationDt
1 100 1/1/12
2 550 1/1/12
1 2000 3/1/12
2 100 4/1/12
1 2100 8/1/12
because claim# 1 was valuated greater than $500 on 3/1/12, claim# 2 was valuated greater than $500 on 1/1/12, and claim# 3 was never valuated greater than $500.
You can use IN:
SELECT *
FROM Table1
WHERE Claim IN (SELECT Claim
FROM Table1
WHERE Total > 500)
Sql Fiddle Demo
Try this:
Select * from table where claim in (Select claim from table where total > 500)
Here table is the name of your table.
This could be the solution
SELECT distinct *
FROM YourTableName
WHERE claim# IN (SELECT DISTINCT claim#
FROM YourTableName
WHERE total > 500)
ORDER BY 3;
Optionally order by
This should work
Select DISTINCT Claim FROM yourtable Where Total > 500
EDIT:
In the case that my initial answer does not fulfill your requirements, then you can use a sub-query. A subquery is a query inside your query (nested queries). The reason we have to do it like that is because if you use something like
Select * FROM yourtable Where Total > 500
Then the result set would only be those moments where the total of the claim was higher than 500, but it would not indicate other moments where it was less or equal than 500.
Therefore, as others have stated, you use a subquery like:
SELECT *
FROM Table1
WHERE Claim IN (SELECT Claim
FROM Table1
WHERE Total > 500)
Note: see that there is a query after the IN keyword, so we have nested queries (or subquery if you prefer).
Why does it work? well, because:
SELECT Claim
FROM Table1
WHERE Total > 500
Will return every claim (only the number of the claim) in which the total was greater than 500 at some point. Therefore, this query will return 1 and 2. If you substitute that in the original query you get:
SELECT *
FROM Table1
WHERE Claim IN (1, 2)
Which will get you every column of every row with Claim numbers equal to either 1 or 2.
You can identify which [Claim#] values satisfy your condition ...
SELECT DISTINCT [Claim#]
FROM YourTable
WHERE [Total] > 500
If that was correct, use it as a subquery which you INNER JOIN to your table, to restrict the result set to only those claims.
SELECT y.[Claim#], y.[Total], y.[ValidationDt]
FROM YourTable AS y
INNER JOIN
(
SELECT DISTINCT [Claim#]
FROM YourTable
WHERE [Total] > 500
) AS sub
ON y.[Claim#] = sub.[Claim#];
Compare this approach vs. the IN() suggestions and see whether you notice any difference in execution speed.
You should be able to use
SELECT [Claim#],[Total],[ValidationDt]
FROM yourtable
WHERE [Claim#] IN (SELECT [Claim#]
FROM yourtable
WHERE Total >= 500)
Should return all values >= 500 for any ValidationDt.

DB2 SQL filter query result by evaluating an ID which has two types of entries

After many attempts I have failed at this and hoping someone can help. The query returns every entry a user makes when items are made in the factory against and order number. For example
Order Number Entry type Quantity
3000 1 1000
3000 1 500
3000 2 300
3000 2 100
4000 2 1000
5000 1 1000
What I want to the query do is to return filter the results like this
If the order number has an entry type 1 and 2 return the row which is type 1 only
otherwise just return row whatever the type is for that order number.
So the above would end up:
Order Number Entry type Quantity
3000 1 1000
3000 1 500
4000 2 1000
5000 1 1000
Currently my query (DB2, in very basic terms looks like this ) and was correct until a change request came through!
Select * from bookings where type=1 or type=2
thanks!
select * from bookings
left outer join (
select order_number,
max(case when type=1 then 1 else 0 end) +
max(case when type=2 then 1 else 0 end) as type_1_and_2
from bookings
group by order_number
) has_1_and_2 on
type_1_and_2 = 2
has_1_and_2.order_number = bookings.order_number
where
bookings.type = 1 or
has_1_and_2.order_number is null
Find all the orders that have both type 1 and type 2, and then join it.
If the row matched the join, only return it if it is type 1
If the row did not match the join (has_type_2.order_number is null) return it no matter what the type is.
A "common table expression" [CTE] can often simplify your logic. You can think of it as a way to break a complex problem into conceptual steps. In the example below, you can think of g as the name of the result set of the CTE, which will then be joined to
WITH g as
( SELECT order_number, min(type) as low_type
FROM bookings
GROUP BY order_number
)
SELECT b.*
FROM g
JOIN bookings b ON g.order_number = b.order_number
AND g.low_type = b.type
The JOIN ON conditions will work so that if both types are present then low_type will be 1, and only that type of record will be chosen. If there is only one type it will be identical to low_type.
This should work fine as long as 1 and 2 are the only types allowed in the bookings table. If not then you can simply add a WHERE clause in the CTE and in the outer SELECT.