Professional Documents
Culture Documents
AS
AS
AS
AS
AS
INT,
INT,
DATETIME,
DATETIME,
INT;
AS
AS
AS
AS
AS
INT,
INT,
DATETIME,
DATETIME,
INT;
BEGIN
SET @dt = CAST(
CONVERT(CHAR(8), GETDATE(), 112)
AS DATETIME);
SET @i = @i + 1;
END
SELECT
'Technique 1' AS technique,
DATEDIFF(ms, @start, GETDATE()) - @overhead AS ms;
-- Technique 2 - Convert to integer and back
SET @start = GETDATE();
SET @i = 1;
WHILE @i <= @iterations
BEGIN
SET @dt = CAST(CAST(GETDATE() AS INT) AS DATETIME);
SET @i = @i + 1;
END
SELECT
'Technique 2' AS technique,
DATEDIFF(ms, @start, GETDATE()) - @overhead AS ms;
-- Technique 3 - Based on DATEDIFF
SET @start = GETDATE();
SET @i = 1;
WHILE @i <= @iterations
BEGIN
SET @dt = DATEADD(
day,
DATEDIFF(day, 0, GETDATE()),
0);
SET @i = @i + 1;
END
SELECT
'Technique 3' AS technique,
DATEDIFF(ms, @start, GETDATE()) - @overhead AS ms;
/*
technique ms
----------- ----------Technique 1 1676
technique ms
----------- ----------Technique 2 633
technique ms
----------- ----------Technique 3 783
*/
GO
-- Extract just the time
-- Accuracy millisecond
SELECT DATEADD(
ms,
DATEDIFF(
ms,
DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0), -- date only
GETDATE()),
0);
SELECT CAST(
CONVERT(CHAR(12), GETDATE(), 114) -- 'hh:mi:ss:mmm'
AS DATETIME);
-- Accuracy second
SELECT DATEADD(
second,
DATEDIFF(
second,
DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0), -- date only
GETDATE()),
0);
SELECT CAST(
CONVERT(CHAR(8), GETDATE(), 114) -- 'hh:mi:ss:mmm'
AS DATETIME);
-- First day of the month
SELECT DATEADD(
month,
DATEDIFF(month, 0, GETDATE()),
0);
-- Last day of the month
SELECT DATEADD(
month,
DATEDIFF(month, 0, GETDATE()) + 1,
0) - 1;
-- First day of the year
SELECT DATEADD(
year,
DATEDIFF(year, 0, GETDATE()),
0);
-- Last day of the year
SELECT DATEADD(
year,
DATEDIFF(year, 0, GETDATE()) + 1,
0) - 1;
-- First minute of the hour
SELECT DATEADD(
hour,
DATEDIFF(hour, 0, GETDATE()),
0);
-- Last minute of the hour
SELECT DATEADD( minute, -1,
DATEADD(
hour,
DATEDIFF(hour, 0, GETDATE()) + 1,
0) );
-- Last occurrence of a weekday
-- Last Monday (Inclusive)
SELECT DATEADD(
day,
DATEDIFF(
day,
0, -- Base Monday date
GETDATE()) /7*7,
0); -- Base Monday date
-- Formatted in one line
SELECT DATEADD(day, DATEDIFF(day, 0, GETDATE()) /7*7, 0);
SELECT DATEADD(day, DATEDIFF(day, 1, GETDATE()) /7*7, 1);
-- Last Sunday
SELECT DATEADD(day, DATEDIFF(day, 6, GETDATE()) /7*7, 6);
-- Last Tuesday
SELECT
DATEADD(
day,
DATEDIFF(day, 0 /* Base Date */, GETDATE()) -- diff
- (DATEDIFF(day, 1 /* Base Tuesday Date */, GETDATE()) % 7), -- offset
0 /* Base Date */);
-- Last Sunday
SELECT
DATEADD(
day,
DATEDIFF(day, 0 /* Base Date */, GETDATE())
- (DATEDIFF(day, 6 /* Base Sunday Date */, GETDATE()) % 7),
0 /* Base Date */);
-- Last Tuesday
SELECT
DATEADD(
day,
DATEDIFF(day, 0 /* Base Date */, GETDATE())
- (DATEPART(weekday, GETDATE() + @@DATEFIRST
- 2 /* datefirst is Tuesday */) - 1),
0 /* Base Date */);
-- Last Sunday
SELECT
DATEADD(
day,
DATEDIFF(day, 0 /* Base Date */, GETDATE())
- (DATEPART(weekday, GETDATE() + @@DATEFIRST
- 7 /* datefirst is Sunday */) - 1),
0 /* Base Date */);
-- Last Monday (Inclusive - Reminder)
SELECT DATEADD(day, DATEDIFF(day, 0, GETDATE()) /7*7, 0);
-- Last Monday (Exclusive)
SELECT DATEADD(day, DATEDIFF(day, 0, GETDATE()-1) /7*7, 0);
-- Next Monday (Inclusive)
SELECT DATEADD(day, DATEDIFF(day, 0, GETDATE()-1) /7*7 + 7, 0);
-- Next Tuesday (Inclusive)
SELECT
DATEDIFF(year, @birth_date, GETDATE())
- CASE WHEN 100 * MONTH(GETDATE()) + DAY(GETDATE())
< 100 * MONTH(@birth_date) + DAY(@birth_date)
THEN 1 ELSE 0
END;
GO
-- Calculate age of employees
SELECT EmployeeID, FirstName, LastName, BirthDate,
DATEDIFF(year, BirthDate, GETDATE())
- CASE WHEN 100 * MONTH(GETDATE()) + DAY(GETDATE())
< 100 * MONTH(BirthDate) + DAY(BirthDate)
THEN 1 ELSE 0
END AS Age
FROM dbo.Employees;
-- Cleanup
DELETE FROM dbo.Employees WHERE EmployeeID > 9;
GO
---------------------------------------------------------------------- Grouping Time Intervals
--------------------------------------------------------------------USE tempdb
GO
IF OBJECT_ID('Sessions') IS NOT NULL
DROP TABLE Sessions
GO
CREATE TABLE Sessions
(
surrogate_key int
NOT NULL IDENTITY(1, 1),
username
varchar(10) NOT NULL,
starttime
smalldatetime NOT NULL,
endtime
smalldatetime NOT NULL,
CONSTRAINT PK_Sessions_surrogate_key
PRIMARY KEY NONCLUSTERED(surrogate_key),
CONSTRAINT CHK_endtime_gteq_starttime
CHECK (endtime >= starttime)
)
INSERT INTO Sessions VALUES('User1', '20011201 08:00', '20011201 08:30')
INSERT INTO Sessions VALUES('User1', '20011201 08:30', '20011201 09:00')
INSERT INTO Sessions VALUES('User1', '20011201 09:00', '20011201 09:30')
INSERT INTO Sessions VALUES('User1', '20011201 10:00', '20011201 11:00')
INSERT INTO Sessions VALUES('User1', '20011201 10:30', '20011201 12:00')
INSERT INTO Sessions VALUES('User1', '20011201 11:30', '20011201 12:30')
INSERT INTO Sessions VALUES('User2', '20011201 08:00', '20011201 10:30')
INSERT INTO Sessions VALUES('User2', '20011201 08:30', '20011201 10:00')
INSERT INTO Sessions VALUES('User2', '20011201 09:00', '20011201 09:30')
INSERT INTO Sessions VALUES('User2', '20011201 11:00', '20011201 11:30')
INSERT INTO Sessions VALUES('User2', '20011201 11:32', '20011201 12:00')
INSERT INTO Sessions VALUES('User2', '20011201 12:04', '20011201 12:30')
INSERT INTO Sessions VALUES('User3', '20011201 08:00', '20011201 09:00')
endtime
-------------2001-12-01 09:
2001-12-01 12:
2001-12-01 10:
2001-12-01 11:
2001-12-01 12:
2001-12-01 12:
2001-12-01 09:
2001-12-01 09:
username,
starttime,
(SELECT MIN(endtime)
FROM (...EndTimes...) AS E
WHERE E.username = S.username
AND endtime >= starttime) AS endtime
FROM (...StartTimes...) AS S
GO
SELECT
username,
starttime,
(SELECT MIN(endtime)
FROM (SELECT DISTINCT username, endtime
FROM Sessions AS S1
WHERE NOT EXISTS
(SELECT *
FROM Sessions AS S2
WHERE S2.username = S1.username
AND S2.endtime > S1.endtime
AND S2.starttime <= S1.endtime)) AS E
WHERE E.username = S.username
AND endtime >= starttime) AS endtime
FROM (SELECT DISTINCT username, starttime
FROM Sessions AS S1
WHERE NOT EXISTS
(SELECT *
FROM Sessions AS S2
WHERE S2.username = S1.username
AND S2.starttime < S1.starttime
AND S2.endtime >= S1.starttime)) AS S
GO
WITH StartTimes AS
(
SELECT DISTINCT username, starttime FROM Sessions AS S1
WHERE NOT EXISTS
(SELECT * FROM Sessions AS S2
WHERE S2.username = S1.username
AND S2.starttime < S1.starttime
AND S2.endtime >= S1.starttime)
),
EndTimes AS
(
SELECT DISTINCT username, endtime FROM Sessions AS S1
WHERE NOT EXISTS
(SELECT * FROM Sessions AS S2
WHERE S2.username = S1.username
AND S2.endtime > S1.endtime
AND S2.starttime <= S1.endtime)
)
SELECT username, starttime,
(SELECT MIN(endtime) FROM EndTimes AS E
WHERE E.username = S.username
AND endtime >= starttime) AS endtime
FROM StartTimes AS S;
GO
---------------------------------------------------------------------- Group By Week
--------------------------------------------------------------------USE Northwind;
SELECT
weekstart,
weekstart + 6 AS weekend,
COUNT(*) AS numorders
FROM (SELECT OrderDate,
OrderDate DATEPART(weekday,
OrderDate + @@DATEFIRST - 1) + 1 AS weekstart
FROM Orders) AS O
GROUP BY weekstart
ORDER BY weekstart;
GO
---------------------------------------------------------------------- Working Days
---------------------------------------------------------------------- Creation script for function fn_workingdays
CREATE FUNCTION dbo.fn_workingdays
(
@from_dt AS DATETIME,
@to_dt
AS DATETIME,
@datefirst AS INT
) RETURNS INT
AS
BEGIN
RETURN
(
SELECT
days/7*5 + days%7
- CASE WHEN 6 BETWEEN from_weekday AND to_weekday
THEN 1 ELSE 0 END
- CASE WHEN 7 BETWEEN from_weekday AND to_weekday
THEN 1 ELSE 0 END
FROM ( SELECT days, from_weekday,
from_weekday + days%7 - 1 AS to_weekday
FROM ( SELECT
DATEDIFF(day, @from_dt, @to_dt) + 1 AS days,
DATEPART(weekday, @from_dt + @@DATEFIRST - @datefirst)
AS from_weekday
) AS D1
) AS D2
);
END
GO
SELECT dbo.fn_workingdays('20070212', '20070223', 1)
SELECT dbo.fn_workingdays('20070212', '20070223', 7)