I try to sum value in pervious rows, I want to sum the pervious quantity "Stock on hand" and put the result in each row, example
ItemID
Qty
Stockon Hand ( the result updated in this column)
1000
1
1
1000
5
6 ( sum qty previous in pervious row plus the qty in the current row)
1000
2
8 ( sum qty previous in pervious row plus the qty in the current row)
1000
1
9 ( sum qty previous in pervious row plus the qty in the current row)
How can I update the column "Stock on hand" by summing the qty in the current row and previous rows?
select ItemID, Qty
, sum(qty) over (order by itemid rows between 1 preceding and 1 preceding) as previous_Qty
from #Stock
order by itemid
Here is a working example. Note, I took the liberty of adding an column for a proper sequence... ID, but you could use a date column as well
You may also notice that I added partition by ItemID
Declare #YourTable Table ([ID] int,[ItemID] int,[Qty] int)
Insert Into #YourTable Values
(1,1000,1)
,(2,1000,5)
,(3,1000,2)
,(4,1000,1)
Select *
,OnHand = sum(Qty) over (partition by ItemID order by ID ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
from #YourTable
Results
ID ItemID Qty OnHand
1 1000 1 1
2 1000 5 6
3 1000 2 8
4 1000 1 9
Related
On a Rails (5.2) app with PostgreSQL I have 2 tables: Item and ItemPrice where an item has many item_prices.
Table Item
id
name
1
poetry book
2
programming book
Table ItemPrice
id
item_id
price
1
1
4
2
2
20
3
1
8
4
1
6
5
2
22
I am trying to select all the items for which the last price (price of the last offer price attached to it) is smaller than the one before it
So in this example, my request should only return item 1 because 6 < 8, and not item 2 because 22 > 20
I tried various combinations of Active records and SQL subqueries that would allow me to compare the last price with the second to last price but failed so far.
ex Item.all.joins(:item_prices).where('EXISTS(SELECT price FROM item_prices ORDER BY ID DESC LIMIT 1 as last_price WHERE (SELECT price FROM item_prices ... can't work it out..
You can do it as follows using ROW_NUMBER and LAG:
LAG to get the previous row based on a condition
WITH ranked_items AS (
SELECT m.*,
ROW_NUMBER() OVER (PARTITION BY item_id ORDER BY id DESC) AS rn,
LAG(price,1) OVER (PARTITION BY item_id ORDER BY id ) previous_price
FROM ItemPrice AS m
)
SELECT it.*
FROM ranked_items itp
inner join Item it on it.id = itp.item_id
WHERE rn = 1 and price < previous_price
Demo here
So my problem is my discount number is blowing up because an order has a discount for the entire order, but I am making a dataset where there are multiple lines for each order to represent each product in the order. Instead of the discount only applying once to the order, it adds the discount for every line.
what is happening
order_id
product_id
quantity
amount
discount
1
a
1
5
0
2
a
1
5
7
2
b
1
10
7
3
a
1
5
5
3
b
1
10
5
3
c
1
15
5
what i want
order_id
product_id
quantity
amount
discount
1
a
1
5
0
2
a
1
5
7
2
b
1
10
0
3
a
1
5
5
3
b
1
10
0
3
c
1
15
0
I just want the discount to be applied once per order, and my join is using order_id so that is why the discount is applying multiple times. I would attach my code, but it's a decent sized CTE
Figured it out. I did need to use a row_number() Over Partition by Order id, but I was also losing records if the order had more than 1 item. The solution was to use a CASE WHEN statement.
CASE WHEN ORDER_ROW_COUNT = 1 THEN DISCOUNT ELSE 0 END
this allowed me to keep the records without duplicating the discounts
You’re joining on a field that isn’t unique so the join is returning all the records for that order Id and therefore the discount is being applied to all the records for that order Id. You need some sort of differentiator field. Something that is unique in each orders data set.
Example:
Select *, row_number () over(partition by order_id order by order_id) as rownumber into #temp from table
This should give you something like in the picture.
rownumber table image
Then join on order_Id = order_Id and rownumber =1 and this would only update the first record for each order.
suppose I have the following table in teradata sql.
How do I get the 'final' column.
The first value is equal to the 'mount' column, the second is equal to final - price (10-1), and the third is equal (9-2).
hour mount price
0 10 1
1 10 2
2 10 3
hour mount price final
0 10 1 10
1 10 2 9
2 10 3 7
You seem to want a cumulative sum -- and then the difference from mount:
select hour, mount price,
(mount + price -
sum(price) over (order by hour rows between unbounded preceding and current row)
) as final
from t;
You really want the sum up to the preceding row. But if you use:
sum(price) over (order by hour rows between unbounded preceding and 1 preceding)
then you will need to deal with NULL values. Instead, I just add price in from the current row and then let the cumulative sum include that price.
I have mapping table for RFQ(request for quotation) and Vendor's bid amount with version.
Table :
id rfq_id(FK) vendor_id(FK) amount version
-----------------------------------------------
1 1 1 100 1
2 1 1 90 2
3 1 1 80 3
4 1 2 50 1
5 1 7 500 1
6 1 7 495 2
7 1 7 500 3
8 1 7 525 4
9 1 7 450 5
10 1 7 430 6
11 2 1 200 1
12 2 2 300 1
13 2 2 350 2
14 2 3 40 1
15 3 4 70 1
In above table, I want analysis for vendor's first and last bid for particular rfq_id.
Expected Output for rfq_id=1 :
vendor_id first_bid last_bid
---------------------------------
1 100 80
2 50 50
7 500 430
From Postgres : get min and max rows count in many to many relation table I have came to know about window and partition. So I have tried below query.
SELECT
vendor_id,
version,
amount,
first_value(amount) over w as first_bid,
last_value(amount) over w as last_bid,
row_number() over w as rn
FROM
rfq_vendor_version_mapping
where
rfq_id=1
WINDOW w AS (PARTITION BY vendor_id order by version)
ORDER by vendor_id;
With above query, every vendor's maximum rn is my output.
http://sqlfiddle.com/#!15/f19a0/7
Window functions add columns to all the existing rows, instead of grouping input rows into a single output row. Since you are only interested in the bid values, use a DISTINCT clause on the fields of interest.
Note that you need a frame clause for the WINDOW definition to make sure that all rows in the partition are considered. By default, the frame in the partition (the rows that are being used in calculations) runs from the beginning of the partition to the current row. Therefore, the last_value() window function always returns the value of the current row; use a frame of UNBOUNDED PRECEDING TO UNBOUNDED FOLLOWING to extend the frame to the entire partition.
SELECT DISTINCT
vendor_id,
version,
amount,
first_value(amount) OVER w AS first_bid,
last_value(amount) OVER w AS last_bid
row_number() over w as rn
FROM
rfq_vendor_version_mapping
WHERE rfq_id = 1
WINDOW w AS (PARTITION BY vendor_id ORDER BY version
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
ORDER BY vendor_id;
You have to GROUP BY vendor_id because you want just one row per vendor_id:
SELECT
vendor_id,
MAX(CASE WHEN rn = 1 THEN amount END) AS first_bid,
MAX(CASE WHEN rn2 = 1 THEN amount END) AS last_bid
FROM (
SELECT
vendor_id,
version,
amount,
row_number() over (PARTITION BY vendor_id order BY version) as rn,
row_number() over (PARTITION BY vendor_id order BY version DESC) as rn2
FROM
rfq_vendor_version_mapping
WHERE
rfq_id=1) AS t
GROUP BY vendor_id
ORDER by vendor_id;
The query uses conditional aggregation in order to extract amount values that correspond to first and last bid.
Demo here
Without ORDER BY OLAP-functions default to ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING but with ORDER BY this changes to ROW UNBOUNDED PRECEDING.
You were quite close, but you need two different windows:
select vendor_id, amount as first_bid, last_bid
from
(
SELECT
vendor_id,
version,
amount,
last_value(amount) -- highest version's bid
over (PARTITION BY vendor_id
order by version
rows between unbiunded preceding and unbounded following) as last_bid,
row_number()
over (PARTITION BY vendor_id
order by version) as rn
FROM
rfq_vendor_version_mapping
where
rfq_id=1
) as dt
where rn = 1 -- row with first version/bid
ORDER by vendor_id;
I am working on an Access database which is used for forecasting purchases and I am trying to create a query in which would give me list of records with valid prices and row sums.
I am running into problems when I try to combine prices to quantities. I have following tables
Table that contains forecasting data (columns not relevant for this query omitted)
need_rows
ID product_id qty use_date
----------------------------
1 1 100 1.1.2014
2 1 50 15.1.2014
...
And table for prices
prices
ID product_id price valid_from
----------------------------------
1 1 1 1.12.2013
2 1 2 24.12.2013
3 1 5 10.1.2014
...
Query resulst should be something like below:
result of query
product_id use_date qty price sum
---------------------------------------
1 1.1.2014 100 2 200
1 15.1.2014 50 5 250
...
Meaning that I need to fetch valid price to each of the rows based on the use_date from need_rows and valid_from date from prices. Valid prices is the one that has valid_from date equal or most recent to use_date.
Below is one of the approaches I have tried with no luck.
SELECT prices.price
FROM prices
WHERE (((prices.product_id)=[product_id]) AND ((prices.valid_from)=
(SELECT Max(prices.valid_from) AS valid
FROM prices
WHERE (((prices.product_id)=[product_id]) AND ((prices.valid_from)<=[use_date]));).));
Any help is appreciated!
SELECT need_rows.Id
, need_rows.qty
, need_rows.product_id
, (SELECT TOP 1 price
FROM prices
WHERE need_rows.product_id = prices.product_id
AND need_rows.use_date >= prices.valid_from
ORDER BY prices.valid_from DESC) AS currentprice
FROM need_rows;