SQL - Compare rows by id, date and amount - sql

I need to SELECT a row in which issue_date = maturity_date of another row with same id, and same amount_usd.
I tried with self join, but I do not get right result.
Here is a simplified version of my table:
ID ISSUE_DATE MATURITY_DATE AMOUNT_USD
1 2010-01-01 00:00:00.000 2015-12-01 00:00:00.000 5000
1 2010-01-01 00:00:00.000 2001-09-19 00:00:00.000 700
2 2014-04-09 00:00:00.000 2019-04-09 00:00:00.000 400
1 2015-12-01 00:00:00.000 2016-12-31 00:00:00.000 5000
5 2015-02-24 00:00:00.000 2015-02-24 00:00:00.000 8000
4 2012-11-29 00:00:00.000 2015-11-29 00:00:00.000 10000
3 2015-01-21 00:00:00.000 2018-01-21 00:00:00.000 17500
2 2015-02-02 00:00:00.000 2015-12-05 00:00:00.000 12000
1 2015-01-12 00:00:00.000 2018-01-12 00:00:00.000 18000
2 2015-12-05 00:00:00.000 2016-01-10 00:00:00.000 12000
Result should be:
ID ISSUE_DATE MATURITY_DATE AMOUNT_USD
1 2015-12-01 00:00:00.000 2016-12-31 00:00:00.000 5000
2 2015-12-05 00:00:00.000 2016-01-10 00:00:00.000 12000
Thanks in advance!

Do following: http://sqlfiddle.com/#!6/c0a02/1
select a.id, a.issue_date, a.maturity_date, a.amount_usd
from tbl a
inner join tbl b
on a.id = b.id
and a.maturity_date = b.issue_date
-- added to prevent same maturity date and issue date
where a.maturity_date <> a.issue_date
Output:
| id | issue_date | maturity_date | amount_usd |
|----|----------------------------|----------------------------|------------|
| 1 | January, 01 2010 00:00:00 | December, 01 2015 00:00:00 | 5000 |
| 2 | February, 02 2015 00:00:00 | December, 05 2015 00:00:00 | 12000 |

Related

R translation into SQL gap fill

I have a R script that I need to migrate into SQL. In R I can use the tidyr::complete to fill in the gaps no worries. And when I know I can do it in SQL with the cross join function. the problem arises when I want to maintain some of the nulls that exist.
I reduced the results here for simplicity but the sequence would go
if month1 = 2012-01-01 then month2 would sequence every month from 2012-01-01 until today month
if month1 = 2020 then month2 would sequence from 2020-01-01 to 2022-11-01
month1
month2
units
2012-01-01
null
10
2012-01-01
2012-01-01
null
2012-01-01
2012-03-01
15
2012-01-01
2013-01-01
12
2012-01-01
2013-04-01
17
2012-01-01
2013-05-05
5
Ideally I would get
month1
month2
units
2012-01-01
null
10
2012-01-01
2012-01-01
null
2012-01-01
2012-02-01
null
2012-01-01
2012-03-01
15
2012-01-01
2013-01-01
12
2012-01-01
2013-02-01
null
2012-01-01
2013-03-01
null
2012-01-01
2013-04-01
17
2012-01-01
2013-05-05
5
but in SQL I am getting
month1
month2
units
2012-01-01
2012-01-01
null
2012-01-01
2012-02-01
null
2012-01-01
2012-03-01
15
2012-01-01
2013-01-01
12
2012-01-01
2013-02-01
null
2012-01-01
2013-03-01
null
2012-01-01
2013-04-01
17
2012-01-01
2013-05-05
5
SELECT
seq.*
, COALESCE(m.n, 0) AS termed
FROM (
SELECT *
FROM (
SELECT DISTINCT month1
FROM table1
WHERE submit_dt IS NOT NULL
) sign
CROSS JOIN (
SELECT DISTINCT month2
FROM table1
WHERE submit_dt IS NOT NULL
)
WHERE month2 >= mmonth1 and month2 is not null
) seq
LEFT JOIN (
SELECT
t2.month1,
, t2.month2
, COUNT(*) AS units
FROM table2 t2
GROUP BY 1,2
) u ON u.month1 = seq.month1 AND u.month2 = seq.month2
Here is the R version that gives me what I want
df
<- (month1, month2, units) %>%
group_by(month1) %>%
tidyr::complete(month2 = seq.Date(as.Date("2012-01-01"), floor_date(today(), "month"), "month"))
Any help is appreciated. I know it is something super simple I am missing. Thanks
So you want the gaps filled for month year 2012 from 2012-01-01 - currentdate
and the same goes for every year in month1
the foolowing extract first all unique years in the month1 generates all dates from the extract year till now and joins it to the orignal table
CREATE TABLE tab1
("month1" timestamp, "month2" timestamp, "units" varchar(4))
;
INSERT INTO tab1
("month1", "month2", "units")
VALUES
('2012-01-01', NULL, '10'),
('2012-01-01', '2012-01-01', NULL),
('2012-01-01', '2012-03-01', '15'),
('2012-01-01', '2013-01-01', '12'),
('2012-01-01', '2013-04-01', '17'),
('2012-01-01', '2013-05-05', '5'),
('2020-01-01', '2020-01-01', '5')
;
CREATE TABLE
INSERT 0 7
SELECT s.date1
,COALESCE(t."month2",s.date2) as month2
,t."units"
FROM (
SELECT (t._year || '-01-01') ::date as date1, generate_series( (t._year || '-01-01') ::date
, (date_part('year', CURRENT_DATE) || '-12-01') ::date
, interval '1 month'
)::date AS date2
FROM (SELECT DISTINCT
extract(year from "month1") _year FROM tab1) t
) s
LEFT JOIN tab1 t
ON date_trunc('month',t."month1"::date)::date = s.date1
AND date_trunc('month',t."month2"::date)::date = s.date2
ORDER BY 1,2;
date1
month2
units
2012-01-01
2012-01-01 00:00:00
null
2012-01-01
2012-02-01 00:00:00
null
2012-01-01
2012-03-01 00:00:00
15
2012-01-01
2012-04-01 00:00:00
null
2012-01-01
2012-05-01 00:00:00
null
2012-01-01
2012-06-01 00:00:00
null
2012-01-01
2012-07-01 00:00:00
null
2012-01-01
2012-08-01 00:00:00
null
2012-01-01
2012-09-01 00:00:00
null
2012-01-01
2012-10-01 00:00:00
null
2012-01-01
2012-11-01 00:00:00
null
2012-01-01
2012-12-01 00:00:00
null
2012-01-01
2013-01-01 00:00:00
12
2012-01-01
2013-02-01 00:00:00
null
2012-01-01
2013-03-01 00:00:00
null
2012-01-01
2013-04-01 00:00:00
17
2012-01-01
2013-05-05 00:00:00
5
2012-01-01
2013-06-01 00:00:00
null
2012-01-01
2013-07-01 00:00:00
null
2012-01-01
2013-08-01 00:00:00
null
2012-01-01
2013-09-01 00:00:00
null
2012-01-01
2013-10-01 00:00:00
null
2012-01-01
2013-11-01 00:00:00
null
2012-01-01
2013-12-01 00:00:00
null
2012-01-01
2014-01-01 00:00:00
null
2012-01-01
2014-02-01 00:00:00
null
2012-01-01
2014-03-01 00:00:00
null
2012-01-01
2014-04-01 00:00:00
null
2012-01-01
2014-05-01 00:00:00
null
2012-01-01
2014-06-01 00:00:00
null
2012-01-01
2014-07-01 00:00:00
null
2012-01-01
2014-08-01 00:00:00
null
2012-01-01
2014-09-01 00:00:00
null
2012-01-01
2014-10-01 00:00:00
null
2012-01-01
2014-11-01 00:00:00
null
2012-01-01
2014-12-01 00:00:00
null
2012-01-01
2015-01-01 00:00:00
null
2012-01-01
2015-02-01 00:00:00
null
2012-01-01
2015-03-01 00:00:00
null
2012-01-01
2015-04-01 00:00:00
null
2012-01-01
2015-05-01 00:00:00
null
2012-01-01
2015-06-01 00:00:00
null
2012-01-01
2015-07-01 00:00:00
null
2012-01-01
2015-08-01 00:00:00
null
2012-01-01
2015-09-01 00:00:00
null
2012-01-01
2015-10-01 00:00:00
null
2012-01-01
2015-11-01 00:00:00
null
2012-01-01
2015-12-01 00:00:00
null
2012-01-01
2016-01-01 00:00:00
null
2012-01-01
2016-02-01 00:00:00
null
2012-01-01
2016-03-01 00:00:00
null
2012-01-01
2016-04-01 00:00:00
null
2012-01-01
2016-05-01 00:00:00
null
2012-01-01
2016-06-01 00:00:00
null
2012-01-01
2016-07-01 00:00:00
null
2012-01-01
2016-08-01 00:00:00
null
2012-01-01
2016-09-01 00:00:00
null
2012-01-01
2016-10-01 00:00:00
null
2012-01-01
2016-11-01 00:00:00
null
2012-01-01
2016-12-01 00:00:00
null
2012-01-01
2017-01-01 00:00:00
null
2012-01-01
2017-02-01 00:00:00
null
2012-01-01
2017-03-01 00:00:00
null
2012-01-01
2017-04-01 00:00:00
null
2012-01-01
2017-05-01 00:00:00
null
2012-01-01
2017-06-01 00:00:00
null
2012-01-01
2017-07-01 00:00:00
null
2012-01-01
2017-08-01 00:00:00
null
2012-01-01
2017-09-01 00:00:00
null
2012-01-01
2017-10-01 00:00:00
null
2012-01-01
2017-11-01 00:00:00
null
2012-01-01
2017-12-01 00:00:00
null
2012-01-01
2018-01-01 00:00:00
null
2012-01-01
2018-02-01 00:00:00
null
2012-01-01
2018-03-01 00:00:00
null
2012-01-01
2018-04-01 00:00:00
null
2012-01-01
2018-05-01 00:00:00
null
2012-01-01
2018-06-01 00:00:00
null
2012-01-01
2018-07-01 00:00:00
null
2012-01-01
2018-08-01 00:00:00
null
2012-01-01
2018-09-01 00:00:00
null
2012-01-01
2018-10-01 00:00:00
null
2012-01-01
2018-11-01 00:00:00
null
2012-01-01
2018-12-01 00:00:00
null
2012-01-01
2019-01-01 00:00:00
null
2012-01-01
2019-02-01 00:00:00
null
2012-01-01
2019-03-01 00:00:00
null
2012-01-01
2019-04-01 00:00:00
null
2012-01-01
2019-05-01 00:00:00
null
2012-01-01
2019-06-01 00:00:00
null
2012-01-01
2019-07-01 00:00:00
null
2012-01-01
2019-08-01 00:00:00
null
2012-01-01
2019-09-01 00:00:00
null
2012-01-01
2019-10-01 00:00:00
null
2012-01-01
2019-11-01 00:00:00
null
2012-01-01
2019-12-01 00:00:00
null
2012-01-01
2020-01-01 00:00:00
null
2012-01-01
2020-02-01 00:00:00
null
2012-01-01
2020-03-01 00:00:00
null
2012-01-01
2020-04-01 00:00:00
null
2012-01-01
2020-05-01 00:00:00
null
2012-01-01
2020-06-01 00:00:00
null
2012-01-01
2020-07-01 00:00:00
null
2012-01-01
2020-08-01 00:00:00
null
2012-01-01
2020-09-01 00:00:00
null
2012-01-01
2020-10-01 00:00:00
null
2012-01-01
2020-11-01 00:00:00
null
2012-01-01
2020-12-01 00:00:00
null
2012-01-01
2021-01-01 00:00:00
null
2012-01-01
2021-02-01 00:00:00
null
2012-01-01
2021-03-01 00:00:00
null
2012-01-01
2021-04-01 00:00:00
null
2012-01-01
2021-05-01 00:00:00
null
2012-01-01
2021-06-01 00:00:00
null
2012-01-01
2021-07-01 00:00:00
null
2012-01-01
2021-08-01 00:00:00
null
2012-01-01
2021-09-01 00:00:00
null
2012-01-01
2021-10-01 00:00:00
null
2012-01-01
2021-11-01 00:00:00
null
2012-01-01
2021-12-01 00:00:00
null
2012-01-01
2022-01-01 00:00:00
null
2012-01-01
2022-02-01 00:00:00
null
2012-01-01
2022-03-01 00:00:00
null
2012-01-01
2022-04-01 00:00:00
null
2012-01-01
2022-05-01 00:00:00
null
2012-01-01
2022-06-01 00:00:00
null
2012-01-01
2022-07-01 00:00:00
null
2012-01-01
2022-08-01 00:00:00
null
2012-01-01
2022-09-01 00:00:00
null
2012-01-01
2022-10-01 00:00:00
null
2012-01-01
2022-11-01 00:00:00
null
2012-01-01
2022-12-01 00:00:00
null
2020-01-01
2020-01-01 00:00:00
5
2020-01-01
2020-02-01 00:00:00
null
2020-01-01
2020-03-01 00:00:00
null
2020-01-01
2020-04-01 00:00:00
null
2020-01-01
2020-05-01 00:00:00
null
2020-01-01
2020-06-01 00:00:00
null
2020-01-01
2020-07-01 00:00:00
null
2020-01-01
2020-08-01 00:00:00
null
2020-01-01
2020-09-01 00:00:00
null
2020-01-01
2020-10-01 00:00:00
null
2020-01-01
2020-11-01 00:00:00
null
2020-01-01
2020-12-01 00:00:00
null
2020-01-01
2021-01-01 00:00:00
null
2020-01-01
2021-02-01 00:00:00
null
2020-01-01
2021-03-01 00:00:00
null
2020-01-01
2021-04-01 00:00:00
null
2020-01-01
2021-05-01 00:00:00
null
2020-01-01
2021-06-01 00:00:00
null
2020-01-01
2021-07-01 00:00:00
null
2020-01-01
2021-08-01 00:00:00
null
2020-01-01
2021-09-01 00:00:00
null
2020-01-01
2021-10-01 00:00:00
null
2020-01-01
2021-11-01 00:00:00
null
2020-01-01
2021-12-01 00:00:00
null
2020-01-01
2022-01-01 00:00:00
null
2020-01-01
2022-02-01 00:00:00
null
2020-01-01
2022-03-01 00:00:00
null
2020-01-01
2022-04-01 00:00:00
null
2020-01-01
2022-05-01 00:00:00
null
2020-01-01
2022-06-01 00:00:00
null
2020-01-01
2022-07-01 00:00:00
null
2020-01-01
2022-08-01 00:00:00
null
2020-01-01
2022-09-01 00:00:00
null
2020-01-01
2022-10-01 00:00:00
null
2020-01-01
2022-11-01 00:00:00
null
2020-01-01
2022-12-01 00:00:00
null
SELECT 168
fiddle

Output data by putting lag in SQL Server

I have one table as below in SQL Server like below.
SELECT * FROM OverlappingDateRanges
Id startDate EndDate
10001 2020-04-01 00:00:00.000 2020-05-25 00:00:00.000
10001 2020-05-26 00:00:00.000 2020-07-15 00:00:00.000
10001 2020-07-17 00:00:00.000 2020-08-15 00:00:00.000
10001 2020-08-16 00:00:00.000 2020-10-15 00:00:00.000
10001 2020-10-16 00:00:00.000 2020-12-31 00:00:00.000
10002 2020-05-01 00:00:00.000 2020-05-29 00:00:00.000
10002 2020-05-30 00:00:00.000 2020-07-08 00:00:00.000
10002 2020-07-09 00:00:00.000 2020-10-01 00:00:00.000
10002 2020-10-03 00:00:00.000 2020-12-31 00:00:00.000
I want output like below where if there is no date difference between end date and next start date of same id, then then date will continue & its should break if end date and next start date is not in continue.
Output should be:
id startDate endDate
10001 2020-04-01 00:00:00.000 2020-07-15 00:00:00.000
10001 2020-07-17 00:00:00.000 2020-12-31 00:00:00.000
10002 2020-05-01 00:00:00.000 2020-10-01 00:00:00.000
10002 2020-10-03 00:00:00.000 2020-12-31 00:00:00.000
This is a type of gaps-and-islands problem. Identify where each output row starts by looking at the previous end. Then do a cumulative sum and aggregate:
select id, min(startdate), max(enddate)
from (select t.*,
sum(case when prev_enddate >= dateadd(day, -1, startdate) then 0 else 1
end) over (partition by id order by startdate) as grp
from (select t.*,
lag(enddate) over (partition by id order by startdate) as prev_enddate
from t
) t
) t
group by id, grp;
Here is a db<>fiddle.

How to get the 1st of September from the previous September?

If I want to select a date relative to today's date I can do something like:
DateAdd(month, -2, N'1-Jan-2019')
This will give me the 1st of November 2018.
How would I get the Date of the 1st of September, from the previous year?
E.G
Say it's July 2019,
I want the 1st of September 2018, NOT 2019.
However,
Say it's November 2019,
I want the 1st of September 2019, NOT 2018.
How is this possible?
You can do this by subtracting 8 months from your date value and then using the resulting year to build up your September date:
declare #d table(d date);
insert into #d values ('20170101'),('20180101'),('20181101'),('20190101'),('20191001'),('20190901'),('20190921'),('20190808');
select d
,datefromparts(year(dateadd(month,-8,d)),9,1) as PrevSeptDate
,datetimefromparts(year(dateadd(month,-8,d)),9,1,0,0,0,0) as PrevSeptDateTime
from #d
order by d;
Output
+------------+--------------+-------------------------+
| d | PrevSeptDate | PrevSeptDateTime |
+------------+--------------+-------------------------+
| 2017-01-01 | 2016-09-01 | 2016-09-01 00:00:00.000 |
| 2018-01-01 | 2017-09-01 | 2017-09-01 00:00:00.000 |
| 2018-11-01 | 2018-09-01 | 2018-09-01 00:00:00.000 |
| 2019-01-01 | 2018-09-01 | 2018-09-01 00:00:00.000 |
| 2019-08-08 | 2018-09-01 | 2018-09-01 00:00:00.000 |
| 2019-09-01 | 2019-09-01 | 2019-09-01 00:00:00.000 |
| 2019-09-21 | 2019-09-01 | 2019-09-01 00:00:00.000 |
| 2019-10-01 | 2019-09-01 | 2019-09-01 00:00:00.000 |
+------------+--------------+-------------------------+

SQL consolidate consecutive date

Hi could anyone help me with the SQL Query.
I want to display all the consecutive dates in the db where there is at least 2 consecutive dates.
Below are an example of the output what i was hoping for.
here is a list of dates:
2016-06-24 00:00:00.000
2016-06-24 00:00:00.000
2016-06-24 00:00:00.000
2016-06-25 00:00:00.000
2016-06-25 00:00:00.000
2016-06-26 00:00:00.000
2016-05-26 00:00:00.000
2016-05-25 00:00:00.000
2016-04-04 00:00:00.000
2016-06-26 00:00:00.000
----------output----------
| Start Date | End Date | Count | consecutive Date |
| 2016-05-25 00:00:00.000 | 2016-05-25 00:00:00.000 | 1 | 2 |
| 2016-05-25 00:00:00.000 | 2016-05-26 00:00:00.000 | 1 | 2 |
| 2016-06-24 00:00:00.000 | 2016-06-25 00:00:00.000 | 2 | 2 |
| 2016-06-24 00:00:00.000 | 2016-06-26 00:00:00.000 | 2 | 3 |
| 2016-06-25 00:00:00.000 | 2016-06-26 00:00:00.000 | 2 | 2 |
This is what I have currently:
WITH t AS (
SELECT SWITCHOFFSET(CONVERT(DATETIMEOFFSET, dateAvailable), '+08:00') d,
ROW_NUMBER() OVER(ORDER BY dateAvailable) i
FROM user_dateTbl
GROUP BY dateAvailable
)
SELECT MIN(d),MAX(d)
FROM t
GROUP BY DATEDIFF(day,i,d)
please help me out thank you. If your unsure of what I am writing do feel free to write in the comment below.

How to sort data based on two columns by grouping on one column among them?

I have the following set of data.
select * from STATEMENT_HISTORY(nolock) order by stmt_dte desc
stmt_key stmt_dte stmt_start_dte stmt_end_dte
----------- ----------------------- ----------------------- -----------------------
12 2013-10-13 00:00:00.000 2013-07-10 00:00:00.000 2013-08-10 00:00:00.000
11 2013-10-12 00:00:00.000 2013-03-10 00:00:00.000 2013-04-10 00:00:00.000
10 2013-10-11 00:00:00.000 2013-07-10 00:00:00.000 2013-08-10 00:00:00.000
9 2013-10-10 00:00:00.000 2013-09-10 00:00:00.000 2013-10-10 00:00:00.000
8 2013-09-10 00:00:00.000 2013-08-10 00:00:00.000 2013-09-10 00:00:00.000
7 2013-08-10 00:00:00.000 2013-07-10 00:00:00.000 2013-08-10 00:00:00.000
6 2013-07-10 00:00:00.000 2013-06-10 00:00:00.000 2013-07-10 00:00:00.000
5 2013-06-10 00:00:00.000 2013-05-10 00:00:00.000 2013-06-10 00:00:00.000
4 2013-05-10 00:00:00.000 2013-04-10 00:00:00.000 2013-05-10 00:00:00.000
3 2013-04-10 00:00:00.000 2013-03-10 00:00:00.000 2013-04-10 00:00:00.000
2 2013-03-10 00:00:00.000 2013-02-10 00:00:00.000 2013-03-10 00:00:00.000
1 2013-02-10 00:00:00.000 2013-01-10 00:00:00.000 2013-02-10 00:00:00.000
My requirement is as follows.
1. The row with latest stmt_dte should be on top
2. All other rows that match with the stmt_start_dte of the top row should take next place sorted by stmt_dte among them and so on.
Expected output should be in the following order.
stmt_key
--------
12
10
7
11
3
10
9
8
6
5
4
2
1
How do I achieve it? Can some one suggest a better approach?
You seem to be using SQL Server. The logic appears to be:
Keep the records with the same stmt_start_dte together
Order them by the maximum stmt_dte
You can do this by using the max() window function:
select stmt_key, stmt_dte, stmt_start_dte, stmt_end_dte
from (select sh.*, max(stmt_dte) over (partition by stmt_start_dte) as grp
from STATEMENT_HISTORY sh
) sh
order by grp desc, stmt_dte desc;