SUM aggregate function and Subquery -SQL - sql

I'm using MS SQL Server and I have 2 tables.
Supply_list
sl_id(pk) supply_id(fk)* transaction_id Qty
1 14 872670099 3
2 15 872670100 5
3 16 872670101 1
4 16 872670105 4 <
supply_id is a foreign key to the supply_id in amenity table
Supply
supply_id(pk) no_of_units
----------------------------
13 2
14 3
15 6
16 10
The output should be supply_id then the no. of units available which is equal to No_of_units subtracted by the Qty.
output
id units available
-------------------------
13 2
14 0 --> [1]
15 1
16 5 --> [2]
[1] Since based on the supply_list table supply_id 14 has 3 for its Qty
[2] There are two records that contains supply_id 16 so we have to add their qty which are 4 and 1 so we have 5. And that 5 would be subtracted from the no_of_units of supply_id 16 and we will get 5 for units available.

You left outer JOIN the list table to the parent table
Subtract the SUM of the list Qty values from the parent no_of_units value
Use ISNULL in case there are no list rows
Something like
SELECT
S.supply_id,
S.no_of_units - ISNULL(SUM(SL.Qty), 0) AS [units available]
FROM
supply S
LEFT JOIN
supply_list SL ON S.supply_id = SL.supply_id
GROUP BY
S.supply_id, S.no_of_units
This makes the aggregate more obvious but is the same query
SELECT
S.supply_id,
S.no_of_units - ISNULL(SL.SumListQty, 0) AS [units available]
FROM
supply S
LEFT JOIN
(
SELECT supply_id, SUM(Qty) AS SumListQty
FROM supply_list
GROUP BY supply_id
) SL ON S.supply_id = SL.supply_id

Related

SQL compare avg for ProductID with exact value

Assume I have such table
OrderLineID OrderID ProductID OrderedQunatity
1 1 2 18
2 1 10 9
3 2 3 12
4 2 8 2
5 2 14 2
7 4 3 1
8 4 5 3
9 5 6 2
15 4 4 0
What I would like to do is compare every single OrderedQuantity with average orderedQuantity for exact product.
For example OrderedQuantity for OrderID = 2 and ProductID = 3 is equal to 12,
so I check average OrderedQuantity for ProductID = 3, so (12+1)/2 = 6.5 and if it is smaller than exact orderQuantity (in this example 12) I select it.
Can someone help what should i type in SELECT?
Thank you!
One method is a correlated subquery:
select t.*
from t
where t.OrderedQuantity < (select avg(t2.OrderedQuantity)
from t t2
where t2.ProductID
);
Note that some databases do integer averages of integers. So you might need avg(t2.OrderedQuantity * 1.0) to get all values less than the average.

Add up all values in column P that has the same value in column A that come from 2 different tables

I have 2 tables joined and I was wanting to add up the value in the price column with ones that had the same value in the EmployeeID column
EmployeeID Price
2 8
2 5
2 11
2 8
3 6
3 8
5 13
5 16
6 13
8 5
9 10
9 4
Select o.EmployeeID,p.Price
From Orders o
inner join Product p on o.ProductID=p.ProductID
(This is the code I used to display the 2 columns from separate tables.)
EmployeeID Price
2 32
3 14
5 29
6 13
8 5
9 14
This is what I want the table to look like
Consider using group by statement for aggregating values referring to the same attribute. I.e., in your case, the solution might look like
select o.EmployeeID, sum(p.Price)
from Orders o
inner join Product p on o.ProductID=p.ProductID
group by o.EmployeeID

How do I make a query that selects where the SUM equals a fixed value

I've spent that last couple of days searching for a way to make a SQL query that searches the database and returns records where the SUM of the same ID's equal or grater then the value provided.
For this I've been using the W3schools database to test it out in the products table.
More so what I've been trying to do:
SELECT * FROM products
WHERE supplierid=? and SUM(price) > 50
in the "where supplier id" would loop through same suppliers and sum of their price higher than 50 in this case return the records.
In this case it would read supplier ID 1 then add the price of all that supplier 18+19+10=47 now 47 < 50 so it will not print those records at the end. Next supplier ID 2 22+21.35=43.35 and again would not print those records until the sum of price is higher than 50 it will print
I'm working with a DB2 database.
SAMPLE data:
ProductID ProductName SupplierID CategoryID Price
1 Chais 1 1 18
2 Chang 1 1 19
3 Aniseed 1 2 10
4 Chef Anton 2 2 22
5 Chef Anton 2 2 21.35
6 Grandma's 3 2 25
7 Uncle Bob 3 7 30
8 Northwoods 3 2 40
9 Mishi 4 6 97
10 Ikura 4 8 31
11 Queso 5 4 21
12 Queso 5 4 38
13 Konbu 6 8 6
14 Tofu 6 7 23.25
How about:
select * from products where supplierid in (
select supplierid
from products
group by supplierid
having sum(price) > 50
);
The subquery finds out all the supplierid values that match your condition. The main (external) query retrieves all rows that match the list of supplierids.
not tested, but I would expect db2 to have analytic functions and CTEs, so perhaps:
with
basedata as (
select t.*
, sum(t.price) over(partition by t.supplierid) sum_price
from products t
)
select *
from basedata
where supplierid = ?
and sum_price > 50
The analytic function aggregates the price information but does not group the resultset, so you get the rows from your initial result, but restricted to those with an aggregated price value > 50.
The difference to a solution with a subquery is, that the use of the analytic function should be more efficient since it has to read the table only once to produce the result.

Summing Two Columns with a Join in SQL Server

I'm having a bit of issue trying to sum two column together with a left join - running in to grouping problems.
An example of the issue is below:
Table One: [Order]
ID CustomerID
1 512
2 317
3 562
Table Two: [OrderEntry]
OrderID Type ID QuantitySold QuantityReturned
1 A 1 1 0
1 A 2 3 0
1 A 3 1 1
2 A 4 1 1
3 B 5 2 0
What I'm trying to display:
CustomerID ID Sold - Returned
512 1 1
512 1 3
512 1 0
317 2 0
Where [OrderEntry].Type = 'A'
This is very basic SQL:
SELECT
ord.CustomerID
, ord.ID
, orden.QuantitySold - orden.QuantityReturned AS [Sold - Returned]
FROM Order ord
LEFT JOIN OrderEntry orden
ON ord.ID = orden.ID
WHERE orden.Type = 'A'
Here you can use any join as you are using and use concat function on two of your column like this
select concat(OrderEntry.QuantitySold, OrderEntry.QuantityReturned) AS newcolumn_name

How to fill in the gaps in a query of totals with zeroes?

I have a table with data like this
picks
20
20
20
18
17
12
12
9
9
This is the table but I need to get result like this.
Picks Count
20 3
19 0
18 1
17 1
16 0
...up to
1 12
How can we write query to get zero totals for data which doesn't exist in the table?
Arun
Use a subquery to generate all the numbers and then outer join it to your table.
with nos as ( select level as pick_id
from dual
connect by level <= 20 )
select nos.pick_id
, count(*)
from nos
left outer join picks
on nos.pick_id = picks.id
group by nos.pick_id
order by nos.pick_id desc ;