Skip to main content
Rollback to Revision 1
Source Link
wBob
  • 10.4k
  • 2
  • 25
  • 44

Just out of interest, how would you get records between say 28 Feb 2012 and Today? Ask your manager to do it being as it's their idea.

Spoiler warning! For me, I would just skip the ( AND ( OR )) nonsense and go straight to a calendar table. You could also use DATEFROMPARTS in SQL 2012 but that will probably result in a table scan:

-- Ugly; hard to debug, hard to parameterise.
-- There is a deliberate mistake here, can you see it?
SELECT *
FROM dbo.tbl_PlayerActionLog
WHERE ( logYear = 2012 AND logMonth = 2 AND logDay >== 28 )
     OR ( logYear = 2012 AND logMonth > 2 )
     OR logYear > 2012 
  ( logYear = 2013 )
  ANDOR ( logYear < 2014
     OR logYear = 2014 AND logMonth < 8 )
     OR ( logYear = 2014 AND logMonth = 8 AND logDay <= 14 
      )


-- DATEFROMPARTS; ok not bad to maintain, will probably result in a 
-- table scan, and why are we reconstructing DATE again?
-- Could do computed column, and why are we reconstructing DATE again?
SELECT *
FROM dbo.tbl_PlayerActionLog
WHERE DATEFROMPARTS( logYear, logMonth, logDay ) Between '28 Feb 2012' AND GETDATE()


-- Calendar table, easy to maintain and parameterise
SELECT *
FROM dbo.tbl_PlayerActionLog pal
WHERE EXISTS
    (
        SELECT 1
        FROM calendar.main c
        WHERE pal.logYear = c.calendarYear
            AND pal.logMonth = c.calendarMonth
            AND pal.logDay = c.calendarDay
            AND c.calendarDate Between '28 Feb 2012' AND GETDATE()
    )

SELECT *
FROM dbo.tbl_PlayerActionLog2
WHERE logDate Between '28 Feb 2012' AND GETDATE()

In my test rig, your manager's option was actually quite efficient, but you can see there is a problem built in to the design; it would be hard to parameterise and hard to debug. The most efficient was the normal DATE column...

Just out of interest, how would you get records between say 28 Feb 2012 and Today? Ask your manager to do it being as it's their idea.

Spoiler warning! For me, I would just skip the ( AND ( OR )) nonsense and go straight to a calendar table. You could also use DATEFROMPARTS in SQL 2012 but that will probably result in a table scan:

-- Ugly; hard to debug, hard to parameterise.
-- There is a deliberate mistake here, can you see it?
SELECT *
FROM dbo.tbl_PlayerActionLog
WHERE ( logYear = 2012 AND logMonth = 2 AND logDay >= 28 
     OR logYear = 2012 AND logMonth > 2 
     OR logYear > 2012 
      )
  AND ( logYear < 2014
     OR logYear = 2014 AND logMonth < 8 
     OR logYear = 2014 AND logMonth = 8 AND logDay <= 14 
      )


-- DATEFROMPARTS; ok not bad to maintain, will probably result in a 
-- table scan, and why are we reconstructing DATE again?
-- Could do computed column, and why are we reconstructing DATE again?
SELECT *
FROM dbo.tbl_PlayerActionLog
WHERE DATEFROMPARTS( logYear, logMonth, logDay ) Between '28 Feb 2012' AND GETDATE()


-- Calendar table, easy to maintain and parameterise
SELECT *
FROM dbo.tbl_PlayerActionLog pal
WHERE EXISTS
    (
        SELECT 1
        FROM calendar.main c
        WHERE pal.logYear = c.calendarYear
            AND pal.logMonth = c.calendarMonth
            AND pal.logDay = c.calendarDay
            AND c.calendarDate Between '28 Feb 2012' AND GETDATE()
    )

SELECT *
FROM dbo.tbl_PlayerActionLog2
WHERE logDate Between '28 Feb 2012' AND GETDATE()

In my test rig, your manager's option was actually quite efficient, but you can see there is a problem built in to the design; it would be hard to parameterise and hard to debug. The most efficient was the normal DATE column...

Just out of interest, how would you get records between say 28 Feb 2012 and Today? Ask your manager to do it being as it's their idea.

Spoiler warning! For me, I would just skip the ( AND ( OR )) nonsense and go straight to a calendar table. You could also use DATEFROMPARTS in SQL 2012 but that will probably result in a table scan:

-- Ugly; hard to debug, hard to parameterise.
-- There is a deliberate mistake here, can you see it?
SELECT *
FROM dbo.tbl_PlayerActionLog
WHERE ( logYear = 2012 AND logMonth = 2 AND logDay = 28 )
  OR ( logYear = 2012 AND logMonth > 2 )
  OR ( logYear = 2013 )
  OR ( logYear = 2014 AND logMonth < 8 )
  OR ( logYear = 2014 AND logMonth = 8 AND logDay <= 14 )


-- DATEFROMPARTS; ok not bad to maintain, will probably result in a 
-- table scan, and why are we reconstructing DATE again?
-- Could do computed column, and why are we reconstructing DATE again?
SELECT *
FROM dbo.tbl_PlayerActionLog
WHERE DATEFROMPARTS( logYear, logMonth, logDay ) Between '28 Feb 2012' AND GETDATE()


-- Calendar table, easy to maintain and parameterise
SELECT *
FROM dbo.tbl_PlayerActionLog pal
WHERE EXISTS
    (
        SELECT 1
        FROM calendar.main c
        WHERE pal.logYear = c.calendarYear
            AND pal.logMonth = c.calendarMonth
            AND pal.logDay = c.calendarDay
            AND c.calendarDate Between '28 Feb 2012' AND GETDATE()
    )

SELECT *
FROM dbo.tbl_PlayerActionLog2
WHERE logDate Between '28 Feb 2012' AND GETDATE()

In my test rig, your manager's option was actually quite efficient, but you can see there is a problem built in to the design; it would be hard to parameterise and hard to debug. The most efficient was the normal DATE column...

added 54 characters in body
Source Link
ypercubeᵀᴹ
  • 98.6k
  • 13
  • 215
  • 305

Just out of interest, how would you get records between say 28 Feb 2012 and Today? Ask your manager to do it being as it's their idea.

Spoiler warning! For me, I would just skip the ( AND ( OR )) nonsense and go straight to a calendar table. You could also use DATEFROMPARTS in SQL 2012 but that will probably result in a table scan:

-- Ugly; hard to debug, hard to parameterise.
-- There is a deliberate mistake here, can you see it?
SELECT *
FROM dbo.tbl_PlayerActionLog
WHERE ( logYear = 2012 AND logMonth = 2 AND logDay =>= 28 )
  OR (  OR logYear = 2012 AND logMonth > 2 )
  OR (  OR logYear => 20132012 
      )
  ORAND ( logYear < 2014
     OR logYear = 2014 AND logMonth < 8 )
  OR (  OR logYear = 2014 AND logMonth = 8 AND logDay <= 14 
      )


-- DATEFROMPARTS; ok not bad to maintain, will probably result in a 
-- table scan, and why are we reconstructing DATE again?
-- Could do computed column, and why are we reconstructing DATE again?
SELECT *
FROM dbo.tbl_PlayerActionLog
WHERE DATEFROMPARTS( logYear, logMonth, logDay ) Between '28 Feb 2012' AND GETDATE()


-- Calendar table, easy to maintain and parameterise
SELECT *
FROM dbo.tbl_PlayerActionLog pal
WHERE EXISTS
    (
        SELECT 1
        FROM calendar.main c
        WHERE pal.logYear = c.calendarYear
            AND pal.logMonth = c.calendarMonth
            AND pal.logDay = c.calendarDay
            AND c.calendarDate Between '28 Feb 2012' AND GETDATE()
    )

SELECT *
FROM dbo.tbl_PlayerActionLog2
WHERE logDate Between '28 Feb 2012' AND GETDATE()

In my test rig, your manager's option was actually quite efficient, but you can see there is a problem built in to the design; it would be hard to parameterise and hard to debug. The most efficient was the normal DATE column...

Just out of interest, how would you get records between say 28 Feb 2012 and Today? Ask your manager to do it being as it's their idea.

Spoiler warning! For me, I would just skip the ( AND ( OR )) nonsense and go straight to a calendar table. You could also use DATEFROMPARTS in SQL 2012 but that will probably result in a table scan:

-- Ugly; hard to debug, hard to parameterise.
-- There is a deliberate mistake here, can you see it?
SELECT *
FROM dbo.tbl_PlayerActionLog
WHERE ( logYear = 2012 AND logMonth = 2 AND logDay = 28 )
  OR ( logYear = 2012 AND logMonth > 2 )
  OR ( logYear = 2013 )
  OR ( logYear = 2014 AND logMonth < 8 )
  OR ( logYear = 2014 AND logMonth = 8 AND logDay <= 14 )


-- DATEFROMPARTS; ok not bad to maintain, will probably result in a 
-- table scan, and why are we reconstructing DATE again?
-- Could do computed column, and why are we reconstructing DATE again?
SELECT *
FROM dbo.tbl_PlayerActionLog
WHERE DATEFROMPARTS( logYear, logMonth, logDay ) Between '28 Feb 2012' AND GETDATE()


-- Calendar table, easy to maintain and parameterise
SELECT *
FROM dbo.tbl_PlayerActionLog pal
WHERE EXISTS
    (
        SELECT 1
        FROM calendar.main c
        WHERE pal.logYear = c.calendarYear
            AND pal.logMonth = c.calendarMonth
            AND pal.logDay = c.calendarDay
            AND c.calendarDate Between '28 Feb 2012' AND GETDATE()
    )

SELECT *
FROM dbo.tbl_PlayerActionLog2
WHERE logDate Between '28 Feb 2012' AND GETDATE()

In my test rig, your manager's option was actually quite efficient, but you can see there is a problem built in to the design; it would be hard to parameterise and hard to debug. The most efficient was the normal DATE column...

Just out of interest, how would you get records between say 28 Feb 2012 and Today? Ask your manager to do it being as it's their idea.

Spoiler warning! For me, I would just skip the ( AND ( OR )) nonsense and go straight to a calendar table. You could also use DATEFROMPARTS in SQL 2012 but that will probably result in a table scan:

-- Ugly; hard to debug, hard to parameterise.
-- There is a deliberate mistake here, can you see it?
SELECT *
FROM dbo.tbl_PlayerActionLog
WHERE ( logYear = 2012 AND logMonth = 2 AND logDay >= 28 
     OR logYear = 2012 AND logMonth > 2 
     OR logYear > 2012 
      )
  AND ( logYear < 2014
     OR logYear = 2014 AND logMonth < 8 
     OR logYear = 2014 AND logMonth = 8 AND logDay <= 14 
      )


-- DATEFROMPARTS; ok not bad to maintain, will probably result in a 
-- table scan, and why are we reconstructing DATE again?
-- Could do computed column, and why are we reconstructing DATE again?
SELECT *
FROM dbo.tbl_PlayerActionLog
WHERE DATEFROMPARTS( logYear, logMonth, logDay ) Between '28 Feb 2012' AND GETDATE()


-- Calendar table, easy to maintain and parameterise
SELECT *
FROM dbo.tbl_PlayerActionLog pal
WHERE EXISTS
    (
        SELECT 1
        FROM calendar.main c
        WHERE pal.logYear = c.calendarYear
            AND pal.logMonth = c.calendarMonth
            AND pal.logDay = c.calendarDay
            AND c.calendarDate Between '28 Feb 2012' AND GETDATE()
    )

SELECT *
FROM dbo.tbl_PlayerActionLog2
WHERE logDate Between '28 Feb 2012' AND GETDATE()

In my test rig, your manager's option was actually quite efficient, but you can see there is a problem built in to the design; it would be hard to parameterise and hard to debug. The most efficient was the normal DATE column...

Source Link
wBob
  • 10.4k
  • 2
  • 25
  • 44

Just out of interest, how would you get records between say 28 Feb 2012 and Today? Ask your manager to do it being as it's their idea.

Spoiler warning! For me, I would just skip the ( AND ( OR )) nonsense and go straight to a calendar table. You could also use DATEFROMPARTS in SQL 2012 but that will probably result in a table scan:

-- Ugly; hard to debug, hard to parameterise.
-- There is a deliberate mistake here, can you see it?
SELECT *
FROM dbo.tbl_PlayerActionLog
WHERE ( logYear = 2012 AND logMonth = 2 AND logDay = 28 )
  OR ( logYear = 2012 AND logMonth > 2 )
  OR ( logYear = 2013 )
  OR ( logYear = 2014 AND logMonth < 8 )
  OR ( logYear = 2014 AND logMonth = 8 AND logDay <= 14 )


-- DATEFROMPARTS; ok not bad to maintain, will probably result in a 
-- table scan, and why are we reconstructing DATE again?
-- Could do computed column, and why are we reconstructing DATE again?
SELECT *
FROM dbo.tbl_PlayerActionLog
WHERE DATEFROMPARTS( logYear, logMonth, logDay ) Between '28 Feb 2012' AND GETDATE()


-- Calendar table, easy to maintain and parameterise
SELECT *
FROM dbo.tbl_PlayerActionLog pal
WHERE EXISTS
    (
        SELECT 1
        FROM calendar.main c
        WHERE pal.logYear = c.calendarYear
            AND pal.logMonth = c.calendarMonth
            AND pal.logDay = c.calendarDay
            AND c.calendarDate Between '28 Feb 2012' AND GETDATE()
    )

SELECT *
FROM dbo.tbl_PlayerActionLog2
WHERE logDate Between '28 Feb 2012' AND GETDATE()

In my test rig, your manager's option was actually quite efficient, but you can see there is a problem built in to the design; it would be hard to parameterise and hard to debug. The most efficient was the normal DATE column...