Remove Transaction using ID and Date range in Redshift SQL - sql

I want to create a query in redshift that will remove transaction items (Table A) base on its validity date (Table B)
Lets call it table A and Table B
Table A contains all transaction of Items
Table A
Item_Code Date
1. I0001 2019-12-01
2. I0002 2019-12-02
3. I0001 2020-01-01
4. I0003 2020-01-01
then Table 2 contains Item validity date
Table B
Item_Code Valid_From Valid_To
1. I0001 2019-01-01 2019-12-31
2. I0002 2019-01-01 2019-12-31
3. I0003 2019-01-01 2019-12-31
and my expected output will be
Item_Code Date
1. I0001 2019-12-01
2. I0002 2019-12-02

THis will give your expected results
Select * from TableA a where not exists(select 1 from TableB b on a.Date between b.Valid_From
and Valid_To)
And once you sure thats what you want, you delete it with
delete from TableA a where not exists(select 1 from TableB b on a.Date between b.Valid_From
and Valid_To)

I would join both tables and insert the validity as a join condition.
This will delete all invalid items or you can reverse the validity condition to detect which items are invalid
SELECT A.ITEM_CODE,A.DATE
FROM Table a
INNER JOIN TABLE B
ON A.ITEM_CODE=B.ITEM_CODE AND A.DATE=> B.Valid_from AND A.date <= B.Valid_to

Related

CASE statement in the WHERE clause, with further conditioning after THEN

I have a table of invoices and one of contracts that invoices are linked to. However, not every invoice is linked to a contract. I want to return all invoices linked to contracts which are within a timeframe (Starting before 2021-03-01), and also the invoices with no contracts linked at all. I believe this is something like: contract IS null OR CASE WHEN contract IS NOT NULL THEN (condition on timestamp), but I don't know how to write it. Note that the actual conditioning will be done on multiple columns, so I am looking for the general form of multiple sub-conditions under the conditions in the WHERE clause.
Example:
Invoice Table
InvoiceID
ContractID
1
NULL
2
1
3
NULL
4
2
5
3
6
4
Contract Table
ContractID
Contract Start Timestamp
1
2021-01-01 00:00:00
2
2021-02-01 00:00:00
3
2021-03-02 00:00:00
4
2021-05-01 00:00:00
Desired Result
InvoiceID
ContractID
1
NULL
2
1
3
NULL
4
2
maybe a simple left join like this can help you in filtering
select
I.*
from Invoice I
left outer join Contract C -- left join gets even the NULL contractid invoices
on C.ContractID= I.ContractID
where
C.[Contract Start Timestamp] IS NULL
OR C.[Contract Start Timestamp]< '2021-03-01'

Netezza - update one table with max data from another table

I have a table in netezza that I need to update. The columns I am working with are
TABLE A
ID_NO
ENTRY_DATE
PRICE
TABLE B
ID_NO
START_DATE
END_DATE
PRICE
So an example of the data would look like this:
TABLE A
ID_NO
ENTRY_DATE
PRICE
123
2020-05-01
123
2020-08-15
TABLE B
ID_NO
START_DATE
END_DATE
PRICE
123
2019-01-01
2019-11-01
$7.64
123
2020-04-30
2020-05-02
$6.19
123
2020-04-15
2020-08-30
$2.19
I need to update the PRICE in TABLE A to be the max PRICE from TABLE B where a.ENTRY_DATE is between b.START_DATE and b.END_DATE. So the final table should look like this:
TABLE A
ID_NO
ENTRY_DATE
PRICE
123
2020-05-01
$6.19
123
2020-08-15
$2.19
This is what I have so far, but it just ends up taking the max price that fits either row rather than doing the calculation for each row:
update TABLE_A
set PRICE=(select max(b.PRICE)
from TABLE_B b
inner join TABLE_A a on a.ID_NO=b.ID_NO
where a.ENTRY_DATE between b.START_DATE and b.END_DATE)
I don't have access to Netezza, but a usual format would be to use a correlated sub-query.
That is, instead of including TABLE_A again in the query, you refer to the outer reference to TABLE_A...
update
TABLE_A
set
PRICE = (
select max(b.PRICE)
from TABLE_B b
where TABLE_A.ID_NO = b.ID_NO
and TABLE_A.ENTRY_DATE between b.START_DATE and b.END_DATE
)
In this way, the correlated-sub-query is essentially invoked once for each row in TABLE_A and that invocation uses the current row from TABLE_A as its parameters.
An alternative could be...
update
TABLE_A
set
PRICE = revised.PRICE
from
(
select a.ID_NO, a.ENTRY_DATE, max(b.PRICE) AS PRICE
from TABLE_B b
inner join TABLE_A a on a.ID_NO=b.ID_NO
where a.ENTRY_DATE between b.START_DATE and b.END_DATE
group by a.ID_NO, a.ENTRY_DATE
)
AS revised
where
TABLE_A.ID_NO = revised.ID_NO
and TABLE_A.ENTRY_DATE = revised.ENTRY_DATE

Join Runing Sum in TSQL

I would like to join a running sum until a specific time point. E.g. I have two tables
Table A
TimestampOfInterest
2001-01-01
2001-02-01
2001-03-01
Table B
Timestamp Credits
2001-01-01 1
2001-01-05 1
2001-02-10 1
2001-03-15 1
Joining B -> A should lead to
TimestampOfInterest Credits
2001-01-01 0
2001-02-01 2
2001-03-01 3
That is the sum of credits until the given TimestampOfInterest.
Can someone help?
Lazloo
not sure you need join. You can simply do this:
Select TimestampOfInterest,
(Select SUM(Credits)
from TableB
where Timestamp < A.TimeStampOfInterest and Category = A.Category) Credits
From TableA A

How to filter only a subset of data while maintain existing records as is in a table?

[SQL Novice] I have a table that looks like this:
id date
1 2019-01-01
1 2019-01-02
2 2019-03-01
2 2019-05-01
I want to only filter the id column on 2 where date is between 2019-04-01 and 2019-05-01 without impacting id equals 1.
The new table should look like this:
id date
1 2019-01-01
1 2019-01-02
2 2019-03-01
I tried this:
select * from table1 where id =2 and date between 2019-03-01 and 2019-04-01
And get this data set:
id date
2 2019-03-01
I think you want or:
where id = 1 or
(id = 2 and date between '2019-03-01' and '2019-04-01')
for your desired result need
select * from table1 where [date] >= '2019-01-01' and [date] <= '2019-03-01'

T-SQL Programming . Common Table expression

I would need a help in the following scneario. I am using T-SQL
Following is my table details. Say the table name is #tempk
Customer Current_Month Contract Amount
201 2015-09-01 3 100
My requirement is to add 12 months from the current month.that is 2016-09-01. Assuming
I am getting the start date of the month. I need the data in the following format
Customer Renewal_Month Contract_months End_Month Amount
201 2015-09-01 3 2016-09-01 100
201 2015-12-01 3 2016-09-01 100
201 2015-03-01 3 2016-09-01 100
201 2015-06-01 3 2016-09-01 100
The contract column can have any values
The consquent records are incremental of contract columns from the previous records.
I am using the following query. I have a date dimension table called Dim_Date that has date,quareter,year,month etc..
WITH GetProrateCTE (Customer_ID,Renewal_Month,Contract_Months,End_Month,MRR) as
(SELECT Customer_ID,Renewal_Month,Contract_Months,DATEADD(month, 12,Renewal_Month) End_Month,MRR
from #tempk),
GetRenewalMonths (Customer_ID,Renewal_Month,Contract_Months,End_Month,MRR) as
(
SELECT A.Customer_ID,B.Month Renewal_Month,A.Contract_Months,A.End_Month,A.MRR
FROM GetProrateCTE A
INNER JOIN (SELECT Month from DW..Dim_Date B GROUP BY MONTH) B
ON B.Month between A.Renewal_Month and A.End_Month
)
SELECT G.Customer_ID,G.Renewal_Month,G.Contract_Months,G.End_Month,G.MRR
FROM GetRenewalMonths G
Could you please help me to achieve the result. Any help would be greatly appreciated.
I want to do this in Common table Expressions. or would it be better if I go cursor.
You can try in this way -
WITH CTE AS
(SELECT Customer,DATEADD(MM,DATEDIFF(MM,0,Current_Month), 0) AS Renewal_Month,Contract,DATEADD(YEAR,1,Current_Month) AS End_Month,Amount,1 AS Level FROM #tempk
UNION ALL
SELECT t.Customer,DATEADD(MONTH,t.Contract,c.Renewal_Month),t.Contract,DATEADD(YEAR,1,t.Current_Month) AS End_Month,t.Amount,Level + 1
FROM #tempk t join CTE c on t.customer = c.customer
WHERE Level < (12/t.Contract))
SELECT Customer,Renewal_Month,Contract AS Contract_months,End_Month,Amount
FROM CTE
Just append your logic of the date dimension table to this.