THEN CONVERT(VARCHAR(8),DATEADD(YEAR, +1, GETDATE()), 112)+RIGHT(BIRTH,4)
ELSE CONVERT(VARCHAR(4), GETDATE(),112)+RIGHT(BIRTH,4) END
BETWEEN CONVERT(VARCHAR(8), GETDATE(), 112) AND CONVERT(VARCHAR, DATEADD(DAY, 20, GETDATE()) , 112 )
Comment 7
-
군고구마
2013.10.31 18:18
-
javamanyo
2013.10.31 18:46
문자열을 잘라서 구현하긴 했어요, 느려서 질문한거구요 ㅠㅠ
SELECT * FROM MSMST WHERE CASE WHEN CONVERT(VARCHAR(4), GETDATE(),112)+RIGHT(BIRTH,4) <= CONVERT(VARCHAR(8), GETDATE(), 112)
THEN CONVERT(VARCHAR(8),DATEADD(YEAR, +1, GETDATE()), 112)+RIGHT(BIRTH,4)
ELSE CONVERT(VARCHAR(4), GETDATE(),112)+RIGHT(BIRTH,4) END
BETWEEN CONVERT(VARCHAR(8), GETDATE(), 112) AND CONVERT(VARCHAR, DATEADD(DAY, 20, GETDATE()) , 112 ) -
군고구마
2013.11.01 08:47
create table birthday(ID int,bir char(10))insert into birthday values(1,'19881216')insert into birthday values(2,'19850116')alter proc birthday_get@ID int,@d_day int outputasset nocount ondeclare @today intdeclare @bir intselect @today= convert(char(10),GETDATE(),112),@bir=convert(char(4),GETDATE(),121)+SUBSTRING(bir,5,4)from dbo.birthday with(nolock)where ID = @IDset @d_day = @today-@birgodeclare @t intexec birthday_get 1,@t outputselect @t이건 어떨까요?물론 더욱 좋은 의견도 많으실 겁니다.제 짧은 지식으로는 여기까지 밖에 ^^ -
군고구마
2013.11.01 08:48
아 그리고 프로시저화해서
값넣으면 바로 구해지도록 만들었습니다. 또한 년도가 지나도 별 상관없습니다.
만약에 이것보다 약간 더 변형하면 파라미터로 '2013'식으로 년도,ID를 받아서도 구할수 있습니다.
-
폭주
2013.11.01 10:31
속도가 느려지는 이유는 인덱스를 못타서 그런듯 한데요.
생일 컬럼이 인덱스 걸려 있다면
제생각에는 Char 날자와 datetime 날자 컬럼을 만들어서
조인하여 계산 하시면 속도가 좀 좋아 지지 않을까요
더 좋은 방법은 고수분들의 의견 들어보세요
테스트 예제 같이 첨부 합니다.
--멤버테이블
CREATE TABLE TestMember
(
Id INT IDENTITY(10000,1) PRIMARY KEY,
Birth CHAR(8) NOT NULL
)
GO--회원 약 130만건 인써트
DECLARE @SelDate DATETIMESELECT @SelDate='1900-01-01'
WHILE @SelDate != CONVERT(DATE,GETDATE())
BEGIN
INSERT INTO dbo.TestMember
( Birth )
SELECT CONVERT(CHAR(8),@SelDate,112)
SELECT @SelDate += 1
ENDGO
INSERT INTO dbo.TestMember
( Birth )
SELECT Birth FROM dbo.TestMember
GO 5--생일컬럼 인덱스 생성
CREATE NONCLUSTERED INDEX ncIDX ON TestMember(Birth)
GO--달력 테이블 생성
CREATE TABLE TestCalendar
(
StrDt CHAR(8) PRIMARY KEY,
DateDt DATETIME
)
GO
--달력 테이블 데이터 입력
DECLARE @SelDate DATETIMESELECT @SelDate='1900-01-01'
WHILE @SelDate != '2100-01-01'
BEGIN
INSERT INTO dbo.TestCalendar
( StrDt, DateDt )
SELECT CONVERT(CHAR(8),@SelDate,112) ,@SelDate
SELECT @SelDate += 1
ENDGO
CREATE NONCLUSTERED INDEX ncIDX ON TestCalendar(DateDt)
GO--샘플테이블 작성 완료
SET STATISTICS IO ON
SET STATISTICS TIME ON
GO--기존
SELECT *
FROM dbo.TestMember
WHERE CASE WHEN CONVERT(VARCHAR(4), GETDATE(),112)+RIGHT(Birth,4) <= CONVERT(VARCHAR(8), GETDATE(), 112)
THEN CONVERT(VARCHAR(8),DATEADD(YEAR, +1, GETDATE()), 112)+RIGHT(Birth,4)
ELSE CONVERT(VARCHAR(4), GETDATE(),112)+RIGHT(Birth,4) END
BETWEEN CONVERT(VARCHAR(8), GETDATE(), 112) AND CONVERT(VARCHAR, DATEADD(DAY, 20, GETDATE()) , 112 )--테이블 'TestMember'. 검색 수 1, 논리적 읽기 수 3091, 물리적 읽기 수 0, 미리 읽기 수 0, LOB 논리적 읽기 수 0, LOB 물리적 읽기 수 0, LOB 미리 읽기 수 0.
-- CPU 시간 = 6177밀리초, 경과 시간 = 6186밀리초
GO--변경
SELECT A.*
FROM dbo.TestMember A
JOIN dbo.TestCalendar B
ON A.Birth=B.strDt
WHERE CASE WHEN CONVERT(VARCHAR(4), GETDATE(),112)+RIGHT(CONVERT(CHAR(6),DateDt,12),4) <= CONVERT(VARCHAR(8), GETDATE(), 112)
THEN CONVERT(VARCHAR(8),DATEADD(YEAR, +1, GETDATE()), 112)+RIGHT(CONVERT(CHAR(6),DateDt,12),4)
ELSE CONVERT(VARCHAR(4), GETDATE(),112)+RIGHT(CONVERT(CHAR(6),DateDt,12),4) END
BETWEEN CONVERT(VARCHAR(8), GETDATE(), 112) AND CONVERT(VARCHAR, DATEADD(DAY, 20, GETDATE()) , 112 )
--테이블 'TestMember'. 검색 수 1, 논리적 읽기 수 3091, 물리적 읽기 수 0, 미리 읽기 수 0, LOB 논리적 읽기 수 0, LOB 물리적 읽기 수 0, LOB 미리 읽기 수 0.
--테이블 'TestCalendar'. 검색 수 1, 논리적 읽기 수 131, 물리적 읽기 수 0, 미리 읽기 수 0, LOB 논리적 읽기 수 0, LOB 물리적 읽기 수 0, LOB 미리 읽기 수 0.
--CPU 시간 = 920밀리초, 경과 시간 = 922밀리초
--최종SELECT A.*
FROM dbo.TestMember A
JOIN
(
SELECT Sa.*
FROM dbo.TestCalendar Sa
JOIN
(
SELECT * FROM dbo.TestCalendar
WHERE DateDt BETWEEN CONVERT(VARCHAR(8), GETDATE(), 112)
AND CONVERT(VARCHAR, DATEADD(DAY, 20, GETDATE()) , 112 )
) Sb
ON MONTH(Sa.StrDt) = MONTH(Sb.StrDt) AND DAY(Sa.DateDt) = DAY(Sb.DateDt)
)
AS B
ON A.Birth=B.strDt--테이블 'TestMember'. 검색 수 4200, 논리적 읽기 수 12867, 물리적 읽기 수 0, 미리 읽기 수 0, LOB 논리적 읽기 수 0, LOB 물리적 읽기 수 0, LOB 미리 읽기 수 0.
--테이블 'Worktable'. 검색 수 0, 논리적 읽기 수 0, 물리적 읽기 수 0, 미리 읽기 수 0, LOB 논리적 읽기 수 0, LOB 물리적 읽기 수 0, LOB 미리 읽기 수 0.
--테이블 'TestCalendar'. 검색 수 2, 논리적 읽기 수 231, 물리적 읽기 수 0, 미리 읽기 수 0, LOB 논리적 읽기 수 0, LOB 물리적 읽기 수 0, LOB 미리 읽기 수 0.
-- CPU 시간 = 297밀리초, 경과 시간 = 384밀리초GO
--샘플테이블 삭제
DROP TABLE dbo.TestMember
GODROP TABLE dbo.TestCalendar
GO -
건우아빠
2013.11.01 13:45
계산필드를 이용하시는 방법도 고려해 보세요...
속도 개선에는 효과적일듯 합니다.
생일을 조회 하기 위해서는 어떻게는 가공형태가 되기 때문에 인덱스를 효과적으로 타기에는 무리가 있을듯 합니다.
create table test
(
birth_dt varchar(8)
)
ALTER TABLE test
ADD birth_mmdd AS right(birth_dt,4)
GOCREATE NONCLUSTERED INDEX idx_birth_mm ON test (birth_mmdd)
GO -
한태
2016.03.23 18:29
CREATE TABLE [dbo].[birth]([birth] [varchar](10) NULL) ON [PRIMARY]GOinsert into birth values ('19900320'),('20000329'),('20000409'),('20010215'),('20160222'),('20160229')select * from birthSELECT birth AS BIRTHDAYFROM birthWHERE DATEADD( Year, DATEPART( Year, GETDATE()) - DATEPART( Year, birth), birth)BETWEEN GETDATE()AND DATEADD(DD, 20, GETDATE());현재연도의 생일 날을 구한 후 지정한 날짜와 비교하여 20일 안에 생일인 사람을 구하는 식으로 쿼리를 작성했습니다.
http://blog.naver.com/waws01 참고하세요.
문자열 자르기를 이용하시면 할 수 있습니다.