Looking to find a SQL query that will work to join a few tables, where the price column will show the price for a specific date.
The data I'm working wiht only gives me the effective date, so I need to be able to say for product purchased on date X, the price should be Y
Here are my two tables:
Prices table:
Product
Price
Effective Date
Price code
123
$ 2.00
1/1/2020
W
177
$ 5.00
10/2/2021
W
123
$ 2.50
10/7/2021
W
123
$ 7.00
10/7/2021
A
500
$10.00
12/1/2021
W
123
$ 3.00
12/2/2021
W
Purchases table:
Product
Purchase Date
123
11/3/2021
123
12/7/2021
The output I am hoping to get:
Product
Purchase Date
Price
123
11/3/2021
$2.50
123
12/7/2021
$3.00
Here's the code I've tried so far that is not working:
FROM [dbo.Purchases] a
inner join [dbo].[Prices] b
on a.[Product] = b.[Product]
Where [Price code] = 'W'
and MAX(b.[Effective Date]) <= a.[Purchase Date]
select distinct pr.Product
,[Purchase Date]
,first_value(pr.Price) over(partition by pu.Product, pu.[Purchase Date] order by [Effective Date] desc) as Price
from Purchases pu join Prices pr on pr.Product = pu.Product and pr.[Effective Date] <= pu.[Purchase Date] and pr.[Price code] = 'w'
Product
Purchase Date
Price
123
2021-11-03 00:00:00.000
2.5000
123
2021-12-07 00:00:00.000
3.0000
Fiddle
Related
I have two tables, tblWithdraw and tblProfit.
tblWithdraw Table
WithdrawId Date User Price
-----------------------------------------------------
1 2021-02-09 SANDANUWAN 2000.00
2 2021-02-09 GAYAN 300.00
3 2021-02-09 KASUN 1500.00
4 2021-02-09 AMAL 4000.00
5 2021-02-09 UDARA 340.00
6 2021-02-09 SULIN 200.00
7 2021-02-09 PERERA 120.00
tblProfit Table
Id Date Inv.No ItemName ItemCode Qty CostPrice DiscountPrice Amount
----------------------------------------------------------------------------------------------
1 2021-02-09 INV0000001 DELL LAP LP001 5 1500.00 1900.00 9500.00
2 2021-02-09 INV0000001 HP MOUSE MO001 7 2500.00 2940.00 20580.00
3 2021-02-09 INV0000001 PACIFIC FAN FAN001 6 2000.00 4000.00 24000.00
4 2021-02-09 INV0000001 SAMSUNG PHONE PH001 8 1000.00 1350.00 10800.00
This is my question. I want to sum all price from tblWithdraw table according to the date. Its mean withdraw date and profit table must be match. New I want to sum all amount from tblProfit table.Then I want to Subtract like this Price - Amount. Finally I want to show total amount of Profit table after subtracted. I used following join but is not working well. please help me to solve this problem. I want to subtract according to the date.
Select MAX(w.Date)Date, SUM(w.Price)Price, SUM(p.Amount)Amount
From tblWithdraw w
Left Join tblProfit p
ON w.Date = p.CurrentDate
Group by w.Date
Out put is like this. its wrong.
Date Price Amount
2021-02-09 33840.00 454160.00
Here's my CTE-based approach based on the comment which I made on the initial question.
WITH WithDraw AS(
SELECT
[date]
,SUM(price) PRICE
FROM tblWithdraw
GROUP BY [date]
),
Profit AS(
SELECT
[date]
,SUM(amount)AMOUNT
FROM tblProfit
GROUP BY [date]
)
SELECT
W.DATE
,W.PRICE
,P.AMOUNT
FROM WithDraw W
INNER JOIN Profit P ON w.date = p.date;
I'm not sure I fully understand the question, this is how I'm reading it:
Select w.Date,
w.agg_price_by_date,
w.agg_price_by_date - COALESCE(p.agg_amount_by_date, 0) AS diff_price_amount
From (SELECT Date,
SUM(Price) AS agg_price_by_date
FROM tblWithdraw w
GROUP
BY Date
) w
Left Join
(SELECT CurrentDate,
SUM(Amount) AS agg_amount_by_date
FROM tblProfit
GROUP
BY CurrentDate
) p
ON w.Date = p.CurrentDate
I have invoices pending payment, every invoice has two dates, first when the invoice is required to pay and the other when the invoice is paid. I want to know in a period of time the max debt and the avg debt
This is the table
Id Invoice Amount InvoiceDate InvoicePayment
----------- ------- ----------- ----------- -------------
1 Bill 1 314 2019-01-20 2019-03-01
2 Bill 2 205 2019-01-14 2019-02-18
3 Bill 3 90 2019-02-04 2019-02-06
4 Bill 4 456 2019-01-03 2019-04-27
I would like to know the max debt amount in february and the avg debt
You can unpivot with cross apply, and use a window sum to compute the "running" debt at each given point in time. The rest is just filtering and aggregation:
select avg(debt) avg_debt, max(debt) max_debt
from (
select x.dt, sum(x.amount) over(order by x.dt) debt
from mytable t
cross apply (values (invoicedate, amount), (invoicepayment, -amount)) as x(dt, amount)
) t
where dt >= '20200201' and dt < '20200301'
I have been trying to solve this problem now for days.
I have table called Stat with the following simplified structure and sample data:
Customer BankID AccNumb Type Date Amount AccType
Customer 1 Boa 5 Account Statement 2015-01-01 10000,00 Eur
Customer 1 CS 10 Account Statement 2015-04-04 22000,00 Eur
Customer 2 Sa 15 Account Statement 2015-03-13 3000,00 Eur
Customer 2 Sa 40 Account Statement 2015-04-24 1000,00 Eur
Customer 2 Sa 15 Sale Advice 2015-04-16 400,00 Eur
Customer 2 Sa 15 Account Statement 2015-12-24 50,00 Usd
Customer 2 Boa 20 Sale Advice 2015-05-15 6000,00 Eur
Customer 3 Cu 25 Account Statement 2015-11-27 81000,00 Eur
Customer 3 Cu 30 Sale Advice 2015-11-27 3000,00 Usd
Customer 3 Pop 30 Account Statement 2015-11-27 12000,00 Eur
What I'm trying to do is to Select the AccountNumber with the latest date specified. A Customer can also have different Account Numbers on various Banks, so it should also be grouped by BankID and Customer.
I have come this far:
SELECT AccNumb, Customer, BankID,
(SELECT TOP 1 Amount FROM Stat
WHERE AccNumb = y.AccNumb AND Customer = y.Customer AND
BankID = y.BankID AND Type = 'Account Statement' AND
Date = MAX(y.Date) GROUP BY Amount) Amount
FROM Stat y
GROUP BY AccNumb, Customer, BankID
ORDER BY Customer, AccNumb
And it works fine, the problem is i should also add the column AccType and Date
I managed to do this with 2 more subselects (the query takes long but it works).
But now i have the problem that there are also NULL values in Customer (or Date) Column. Now, the account number of these 'NULL' Customers still should be displayed if it's the latest date. I also tried to do the same by joining the table by itself, and it didnt work out.
SELECT x.AccNumber, x.Customer, x.BankID, x.Date, y.Amount, y.AccType
FROM Stat y RIGHT JOIN
(SELECT AccNumber, Customer, BankID, MAX(Date) Date FROM Stat
GROUP BY AccNumber, Customer, BankID) x
ON x.AccNumber = y.AccNumber AND
x.Customer = y.Customer AND
x.BankID = y.BankID AND
x.Date = y.Date
ORDER BY y.Customer, y.AccNumber
But now the 'NULL' Customers only have NULL values in the Amount, Date and AccType Columns, which is not correct.
The output should be something like this
AccNumb Customer BankID Amount Date AccType
111111111 a Boa 1234.40 31.06.2014 Eur
222222222 NULL Boa 5678.40 31.04.2014 Eur
333333333 b Boa 0.00 25.02.2014 Eur
444444444 NULL Boa 9101.40 23.04.2015 Eur
555555555 NULL Boa 1213.40 31.02.2014 Usd
A66666666 c Sa NULL 31.02.2014 Eur
777777777 c Sa 1415.00 31.12.2014 Eur
888888888 c Boa 1617.40 31.12.2014 Usd
999999999 f Pop 5678.64 31.10.2014 Eur
Thanks in advance.
Just use row_number(), if I understand correctly:
select s.*
from (select s.*,
row_number() over (partition by customer, bankId order by date desc) as seqnum
from stat s
) s
where seqnum = 1;
Find the rows with latest dates, i.e. return a row if no other row with same AccountNumber, BankID and Customer but a later Date exists:
select *
from stat s1
where not exists (select 1 from stat s2
where s1.AccountNumber = s2.AccountNumber
and s1.BankID = s2.BankID
and s1.Customer = s2.Customer
and s1.Date < s2.Date)
You're first query works closely to what, I believe, you are looking for. Using it as a base, we can alter to work for you:
SELECT
AccNumb,
Customer,
BankID,
Amount,
Date,
AccType
FROM Stat y
WHERE Date = (SELECT MAX(z.DATE)
FROM Stat z
WHERE z.AccNumb = y.AccNumb
AND z.Customer = y.Customer
AND z.BankID = y.BankID AND Type = 'Account Statement')
ORDER BY Customer, AccNumb
i have a store sales table which looks like below containing two years of data.
If the sales amount is '0' for a particular day for a particular store ,i have to take sales for same day last week.(current day-7)
if those sales are also '0' then sales for current_day-8
if those sales are also '0' then sales for current_day-9
if those sales are also '0' then sales for current_day-10
Sales_table1
day_id week_id sales Store
2/1/2014 201401 34566 1234
2/2/2014 201401 67777 567
2/3/2014 201401 3333 698
2/4/2014 201401 45644 345
2/5/2014 201401 2456 789
**2/6/2014 201401 3456 567**
2/7/2014 201401 5674 780
2/8/2014 201402 3333 1234
2/9/2014 201402 22222 567
2/10/2014 201402 111134 698
2/11/2014 201402 56789 345
2/12/2014 201402 4356 789
**2/13/2014 201402 0 567**
2/14/2014 201402 899 780
please give the query that i can use.
As you have not said which database you are using I'm giving a solution using SQL Server as that's what I'm most familiar with.
The logic of my query is to select all the rows where sales are greater than zero for each store, where the date of the sales info is either the MAX date in the table or the date is less than or equal to the MAX(date)-7 days (effectively exclude any sales in the previous 7 days). I'm doing this because you said you need to take the most recent sale or sales on day -7, -8, -9, etc.
From that set of rows the query then picks the most recent sale date.
;WITH Store_Dates AS (
SELECT store, MAX(day_id) max_date, DATEADD(day, -7, MAX(day_id)) old_date
FROM Sales_Table1
GROUP BY store
)
,Sale_Days AS (
SELECT MAX(day_id) day_id, Sales_Table1.store
FROM Sales_Table1 INNER JOIN Store_Dates
ON Sales_Table1.store = Store_Dates.store
WHERE sales > 0
AND (day_id = max_date
OR day_id <= old_date)
GROUP BY Sales_Table1.store
)
SELECT Sales_Table1.*
FROM Sales_Table1 INNER JOIN Sale_Days
ON Sales_Table1.store = Sale_Days.store
AND Sales_Table1.day_id = Sale_Days.day_id
SQL Fiddle
The only thing my query does not do is stop after going back X number of days. You could do that by limiting the number of rows returned from the Sale_Days query.
COMMISSION table
PRODUCT_ID DATE COMMISSION
1 20110101 27.00
1 20120101 28.00
1 20130705 30.00
2 20110101 17.00
2 20120501 16.00
2 20130101 18.00
...
ORDER table
PRODUCT_ID DATE PRICE
1 20110405 2500
2 20130402 3000
2 20130101 1900
Desired output
PRODUCT_ID DATE PRICE COMMISSION
1 20110405 2500 27.00
2 20130402 3000 16.00
2 20130101 1900 18.00
Commission table records commission % based on the product id and date.
Order table is basically a record of orders placed on a particular date,
I'd like to join two tables and bring the appropriate commission based on the date of the order. For example, you can see that the first order's commission is 27.00 as the date for the product_id 1 falls between 20110101 and 20120101.
How do I do this? Seems like a simple 1 to n relationship but I can't figure it out.
Try
SELECT o.*,
(
SELECT TOP 1 commission
FROM commission
WHERE product_id = o.product_id
AND date <= o.date
ORDER BY date DESC
) commission
FROM [order] o
Here is SQLFiddle demo