Update Table with auto incrementing dates in date column - sql

I want to update a Table with auto incrementing dates in date column in Sql server 2005.

To label newly inserted rows, you could combine an identity column with a calculated field. For example:
declare #t table
(
dayNumber int identity,
Date as dateadd(day, dayNumber-1, '1970-01-01')
)
insert into #t default values
insert into #t default values
insert into #t default values
select * from #t
This prints:
dayNumber Date
1 1970-01-01 00:00:00.000
2 1970-01-02 00:00:00.000
3 1970-01-03 00:00:00.000
To update columns in an existing table with increasing dates, use row_number, like:
declare #t2 table (id int identity, name varchar(50), DateColumn datetime)
insert #t2 (name) values ('Maggie'), ('Tom'), ('Phillip'), ('Stephen')
update t2
set DateColumn = DATEADD(day, rn-1, '1970-01-01')
from #t2 t2
join (
select ROW_NUMBER() over (order by id) rn
, id
from #t2
) t2_numbered
on t2_numbered.id = t2.id
select * from #t2
This prints:
id name DateColumn
1 Maggie 1970-01-01 00:00:00.000
2 Tom 1970-01-02 00:00:00.000
3 Phillip 1970-01-03 00:00:00.000
4 Stephen 1970-01-04 00:00:00.000

Related

Return number of rows dependent on number

Have a table with this
Id
StartDate
NoOfMonths
1
2021-09-01
2
2
2021-09-01
3
And want a query to return this
Id
Date
1
2021-09-01
1
2021-10-01
2
2021-09-01
2
2021-10-01
2
2021-11-01
How can I make this happen?
Here is an example without an additional table:
DECLARE #t TABLE(
ID int
, StartDate date
, NoOfMonths int
)
INSERT INTO #t VALUES
(1, '2021-09-01', 2)
,(2, '2021-09-01', 3);
WITH cte AS(
SELECT ID, StartDate, NoOfMonths
FROM #t
UNION ALL
SELECT ID, DATEADD(MONTH, 1, StartDate), NoOfMonths-1
FROM cte
WHERE NoOfMonths > 1
)
SELECT ID, StartDate
FROM cte
ORDER BY ID, StartDate
This could be solved by having an additional calendar table, which would be populated and maintained by you. The content of the table could be just dates (first days of months). Then you would join records from that calendar table with your original table using DATEADD() function if it's MS SQL server. So something like:
select DateMonth
from CalendarTable ct
inner join YourTable yt
on ct.DateMonth between yt.StartDate and DATEADD (MONTH, yt.NoOfMonths, yt.StartDate)

Finding time differences between each row in a specific column in SQL Server

Still learning SQL, but I'm trying to see if there are any Customers that have a time frame within 24 hours of each other. So in this example ID 1 and 4 meet this criteria.
CustID Date
1 2018-04-10 11:21:00.000
1 2018-03-05 18:14:00.000
1 2018-03-05 22:53:00.000
2 2018-04-10 11:21:00.000
2 2018-03-27 14:57:00.000
2 2018-04-04 20:00:00.000
3 2018-04-10 11:21:00.000
3 2018-02-10 11:21:00.000
3 2018-04-24 11:29:00.000
4 2018-04-10 11:21:00.000
4 2018-04-10 11:20:00.000
4 2018-04-24 11:29:00.000
I'm thinking about doing something like
SELECT CustId
From Cars c
CROSS APPLY(
SELECT Date
FROM Cars
Where Date != c.Date)
WHERE Date - c.Date < 24 hours
Use lag():
select distinct custid
from (select c.*,
lag(c.date) over (partition by c.custid order by c.date) as prev_date
from cars c
) c
where date < dateadd(hour, 24, prev_date);
This answer is based on sql-server, but you should be able to translate as needed. I also assumed you had a requirement where the same datetime between two customers can't be the same. If that's a false assumption, remove the where clause. A simple self-join should get you there.
declare #t table (id int, dt datetime)
insert into #t values ('1','2018-04-10 11:21:00.000')
insert into #t values ('1','2018-03-05 18:14:00.000')
insert into #t values ('1','2018-03-05 22:53:00.000')
insert into #t values ('2','2018-04-10 11:21:00.000')
insert into #t values ('2','2018-03-27 14:57:00.000')
insert into #t values ('2','2018-04-04 20:00:00.000')
insert into #t values ('3','2018-04-10 11:21:00.000')
insert into #t values ('3','2018-02-10 11:21:00.000')
insert into #t values ('3','2018-04-24 11:29:00.000')
insert into #t values ('4','2018-04-10 11:21:00.000')
insert into #t values ('4','2018-04-10 11:20:00.000')
insert into #t values ('4','2018-04-24 11:29:00.000')
select
t1.id, t2.id
from #t t1
join #t t2 on t2.dt between dateadd(hh, -24,t1.dt) and t1.dt and t1.id<>t2.id
where t1.dt<>t2.dt

SQL - How to cross-join two table to repeat values

I have a 2 tables that look like this:
MonthEndDate
2016-06-30 00:00:00.000
2016-07-31 00:00:00.000
2016-08-31 00:00:00.000
2016-09-30 00:00:00.000
2016-10-31 00:00:00.000
2016-11-30 00:00:00.000
2016-12-31 00:00:00.000
AND
MonthEndDate CustomerId Flag
2016-06-30 00:00:00.000 123 1
2016-07-31 00:00:00.000 123 1
2016-08-31 00:00:00.000 123 1
2016-09-30 00:00:00.000 123 1
I would like an output that looks like this:
MonthEndDate CustomerId Flag
2016-06-30 00:00:00.000 123 1
2016-07-31 00:00:00.000 123 1
2016-08-31 00:00:00.000 123 1
2016-09-30 00:00:00.000 123 1
2016-10-31 00:00:00.000 123 0
2016-11-30 00:00:00.000 123 0
2016-12-31 00:00:00.000 123 0
Table 1 is a DimDate table that has month end date.
Table
2 is the CustomerInfo table.
Each customer has a Flag set to 1 whenever that customer has a value for the given Month End.
I want to get an output that will have every Month End Date (that's why I'm suing DimDate table) and when a customer does not have a value for the Month End I want the flag to show 0.
I'm using SQL Server 2005
Here is some sample code I used:
DECLARE #table1 TABLE
(
MonthEndDate DATETIME
)
INSERT INTO #table1
VALUES('2016-06-30 00:00:00.000')
INSERT INTO #table1
VALUES('2016-07-31 00:00:00.000')
INSERT INTO #table1
VALUES('2016-08-31 00:00:00.000')
INSERT INTO #table1
VALUES('2016-09-30 00:00:00.000')
INSERT INTO #table1
VALUES('2016-10-31 00:00:00.000')
INSERT INTO #table1
VALUES('2016-11-30 00:00:00.000')
INSERT INTO #table1
VALUES('2016-12-31 00:00:00.000')
DECLARE #table2 TABLE
(
MonthEndDate DATETIME
,CustomerId INT
,Flag INT
)
INSERT INTO #table2
VALUES('2016-06-30 00:00:00.000',123,1)
INSERT INTO #table2
VALUES('2016-07-31 00:00:00.000',123,1)
INSERT INTO #table2
VALUES('2016-08-31 00:00:00.000',123,1)
INSERT INTO #table2
VALUES('2016-09-30 00:00:00.000',123,1)
SELECt * FROM #table1
SELECt * FROM #table2
You need to do a CROSS JOIN on to get all combinations of MonthEndDate and CustomerId. When you have that, do a LEFT JOIN on table2 to get the Flag:
SELECT
t1.MonthEndDate,
c.CustomerId,
Flag = ISNULL(t2.Flag, 0)
FROM #table1 t1
CROSS JOIN (SELECT DISTINCT CustomerId FROM #table2) c
LEFT JOIN #table2 t2
ON t1.MonthEndDate = t2.MonthEndDate
AND c.CustomerId = t2.CustomerId
I think you just want a left join:
select t1.*, coalesce(t2.flag, 0) as flag
from #table1 t1 left join
#table2 t2
on t1.MonthEndDate = t2.MonthEndDate;

Sql Query create date range with single date column

I have a table containing a single date column say special date (stored as yyyymmdd )
How do i create a date range among the small subset of rows?
Example table contains a date column with following values 01-jan-2010, 01-feb-2010, 01-mar-2010
I need
01-jan-2010 - 01-feb-2010
01-feb-2010 - 01-mar-2010
....
....
Please help.
You can try something like
DECLARE #Table TABLE(
DateVal DATETIME
)
INSERT INTO #Table SELECT '01 Jan 2010'
INSERT INTO #Table SELECT '01 Feb 2010'
INSERT INTO #Table SELECT '01 Mar 2010'
;WITH DateVals AS (
SELECT *,
ROW_NUMBER() OVER(ORDER BY DateVal) RowID
FROM #Table
)
SELECT s.DateVal StartDate,
e.DateVal EndDate
FROM DateVals s INNER JOIN
DateVals e ON s.RowID + 1 = e.RowID
Output
StartDate EndDate
2010-01-01 00:00:00.000 2010-02-01 00:00:00.000
2010-02-01 00:00:00.000 2010-03-01 00:00:00.000
You can avoid the CTE by using
SELECT s.DateVal StartDate,
MIN(e.DateVal) EndDate
FROM #Table s LEFT JOIN
#Table e ON s.DateVal < e.DateVal
GROUP BY s.DateVal
HAVING MIN(e.DateVal) IS NOT NULL
But I do not see why you wish to do so.

Add Missing Date Range to Result Record Set

I have a table containing the working hours for the company. We define the range of the dates and the number of hours for the range.
The number of working hours which is not in the defined range is 9.5 hours.
I want to have the non-defined range with the value of 9.5 added to the result record set.
how should I make the query to get this result?
The table definition and added records:
IF OBJECT_ID ('dbo.tbl_WorkingHours') IS NOT NULL
DROP TABLE dbo.tbl_WorkingHours
GO
CREATE TABLE dbo.tbl_WorkingHours
(
Startdate DATETIME NOT NULL,
EndDate DATETIME NOT NULL,
HoursDefined FLOAT NULL,
Description VARCHAR (255) NULL,
PRIMARY KEY (Startdate,EndDate)
)
INSERT INTO dbo.tbl_WorkingHours
(Startdate,EndDate,HoursDefined,Description)
VALUES
('3/4/2010','3/29/2010',7,'')
INSERT INTO dbo.tbl_WorkingHours
(Startdate,EndDate,HoursDefined,Description)
VALUES
('5/4/2010','5/29/2010',8,'')
The Result of Select * :
Startdate | EndDate | HoursDefined | Description
----------------------------------------------------
3/4/2010 3/29/2010 7
5/4/2010 5/29/2010 8
My desired record set:
Startdate | EndDate | HoursDefined | Description
----------------------------------------------------
1/1/1900 3/3/2010 9.5
3/4/2010 3/29/2010 7
3/30/2010 5/3/2010 9.5
5/4/2010 5/29/2010 8
5/30/2010 1/1/2050 9.5
The below assumes it is not possible to have overlapping ranges or two defined ranges that are contiguous but held as separate rows.
WITH wh AS
(
SELECT Startdate, EndDate, HoursDefined, Description,
ROW_NUMBER() over (order by startdate) as rn
FROM tbl_WorkingHours
)
SELECT Startdate, EndDate, HoursDefined, Description
FROM wh
UNION ALL
SELECT ISNULL(dateadd(day,1,w1.EndDate),'19000101'),
ISNULL(dateadd(day,-1,w2.StartDate),'20500101') , 9.5 AS HoursDefined,''
FROM wh w1 FULL OUTER JOIN wh w2
ON w2.rn = w1.rn+1
ORDER BY Startdate
try something like this:
DECLARE #tbl_WorkingHours table (Startdate DATETIME NOT NULL
,EndDate DATETIME NOT NULL
,HoursDefined FLOAT NULL
,Description VARCHAR (255) NULL
,PRIMARY KEY (Startdate,EndDate)
)
INSERT INTO #tbl_WorkingHours (Startdate,EndDate,HoursDefined,Description) VALUES ('3/4/2010','3/29/2010',7,'')
INSERT INTO #tbl_WorkingHours (Startdate,EndDate,HoursDefined,Description) VALUES ('5/4/2010','5/29/2010',8,'')
;WITH OrderedRows AS
( SELECT
Startdate,EndDate,HoursDefined,Description, ROW_NUMBER() OVER (ORDER BY Startdate,EndDate) AS RowNumber
FROM #tbl_WorkingHours
)
SELECT --before rows
CONVERT(datetime,'1/1/1900') AS Startdate,ISNULL(MIN(Startdate),CONVERT(datetime,'1/2/2050'))-1 AS EndDate,9.5 AS HoursDefined, CONVERT(VARCHAR (255),'') AS Description
FROM #tbl_WorkingHours
UNION ALL
SELECT --actual rows
Startdate,EndDate,HoursDefined,Description
FROM #tbl_WorkingHours
UNION ALL
SELECT --between rows
a.EndDate+1,b.Startdate-1,9.5,''
FROM OrderedRows a
INNER JOIN OrderedRows b ON a.RowNumber=b.RowNumber-1
UNION ALL
SELECT --after rows
ISNULL(MAX(EndDate),CONVERT(datetime,'1/1/2050')) AS Startdate,CONVERT(datetime,'1/2/2050')-1 AS EndDate,9.5 AS HoursDefined, CONVERT(VARCHAR (255),'') AS Description
FROM #tbl_WorkingHours
ORDER BY Startdate,EndDate
OUTPUT:
Startdate EndDate HoursDefined Description
----------------------- ----------------------- ---------------------- -----------
1900-01-01 00:00:00.000 2010-03-03 00:00:00.000 9.5
2010-03-04 00:00:00.000 2010-03-29 00:00:00.000 7
2010-03-30 00:00:00.000 2010-05-03 00:00:00.000 9.5
2010-05-04 00:00:00.000 2010-05-29 00:00:00.000 8
2010-05-29 00:00:00.000 2050-01-01 00:00:00.000 9.5
(5 row(s) affected)