2010-07-20 4 views
2

Ok는 문제가 있음을 알 수 있습니다. 신이 만든 다섯 가지 테이블을 각각 다른 데이터로 알고 있으며, 하나의 테이블에 병합해야합니다.요일의 마지막 레코드가 필요합니다.

첫 번째 문제는 매일 매일 타임 스탬프가 있지만 마지막 레코드 만 추가하면됩니다. 따라서 매일 마지막 레코드를 검색하여 새 테이블에 저장할 수 있습니까?이 테이블의 대부분은 다음과 같습니다. 약 4 억 건의 큰 레코드.

다음 쿼리를 사용하면 마지막 레지스터가 반환되지만 매일 매일 마지막 레지스터를 검색해야합니다 (누군가가 작업을 망쳐 놓고 매일 15 분마다 중복 된 데이터를 많이 생성하므로).

일부는 지금까지이가 2008 년

까지 가서 현재 하루에 2006 년 1 월 (테이블에 따라) 1 일의 범위입니다.

SELECT * FROM [PDP].[dbo].[Existencia_WH_PRISM_BACKUP] 
     WHERE dExD_Fecha = (SELECT MAX(dExD_Fecha) 
     FROM dbo.Existencia_WH_PRISM_BACKUP) 

이것은 SQL 서버 2005 +입니다 그러나 경우에, 나에게 당신은 (당신이 현재 그 일을하는 방법에 대한도 많은 세부 사항) SQL 서버의 버전을 언급하지 않았다

NombreEntidad dExD_Fecha LDWHSE LDLOCN LDRESC LDLOTN LDGRDE LDLOCQ LDUMSR LDRSCL LDRSSC LDQRUM LDRCUM LDPOTF LDREVL LDCLCD LDOOIN LDAVPL LDOHIN LDDVIN LDDWIP LDQYRM LDQYRS LDDLRC LDTLRC LDTRAN LDFIFO LDETD LDETT LDEXPD LDVNNO LDPOSQ LDDTMT LDACTP LDZONE LDAVPT LDRTND LDCDDT LDLSQY LDAGE1 LDAGE2 LDAGE3 LDAGE4 LDAGE5 LDAMIR LDRCLS LDPTAW LDCSPK LDQYOU LDBLNK 
HDZALM 2010-05-28 12:01:00.000 1T A04 405120 K0146  864.000000 CJ PT 40 864.000000 CJ 0.000000  STOC N 2 Y Y N 0.000000 0.000000 1100527 75934 6659304 1100527 1100527 61504 1110527  5 1100527 N A Y   0.000000 9999999 9999999 9999999 9999999 9999999 N Y Y N 0.000000  
HDZALM 2010-05-28 12:01:00.000 1T A04 405120 K0147  1944.000000 CJ PT 40 1944.000000 CJ 0.000000  STOC N 2 Y Y N 0.000000 0.000000 1100527 120112 6665777 1100527 1100527 120051 1110527  5 1100527 N A Y   0.000000 9999999 9999999 9999999 9999999 9999999 N Y Y N 0.000000  
HDZALM 2010-05-28 12:01:00.000 1T A05 405120 K0146  2052.000000 CJ PT 40 2052.000000 CJ 0.000000  STOC N 2 Y Y N 0.000000 0.000000 1100527 54402 6658261 1100527 1100527 54146 1110527  5 1100527 N A Y   0.000000 9999999 9999999 9999999 9999999 9999999 N Y Y N 0.000000  
HDZALM 2010-05-28 12:01:00.000 1T A05 405120 K0147  2160.000000 CJ PT 40 2160.000000 CJ 0.000000  STOC N 2 Y Y N 0.000000 0.000000 1100527 153911 6671885 1100527 1100527 153714 1110527  5 1100527 N A Y   0.000000 9999999 9999999 9999999 9999999 9999999 N Y Y N 0.000000  
HDZALM 2010-05-28 12:01:00.000 1T A06 405120 K0146  4212.000000 CJ PT 40 4212.000000 CJ 0.000000  STOC N 2 Y Y N 0.000000 0.000000 1100527 43743 6657177 1100527 1100527 43625 1110527  5 1100526 N A Y   0.000000 9999999 9999999 9999999 9999999 9999999 N Y Y N 0.000000  
+2

당신은 출력에 열 이름을 추가 할 수 있습니까? – mrdenny

+0

죄송합니다. 칼럼이 부족해서 죄송 합니다만, 50 개 이상의 기둥이있는 것처럼 잘라 냈습니다.다른 방법이 없다면 – Enrique

+0

커서를 사용하지 마십시오. 다른 방법이 없습니까? –

답변

0

이 시도 :

SELECT e.* 
FROM [PDP].[dbo].[Existencia_WH_PRISM_BACKUP] e 
INNER JOIN (
    SELECT MAX(dExd_Fecha) AS dExd_Fecha_Max 
    FROM [PDP].[dbo].[Existencia_WH_PRISM_BACKUP] 
    GROUP BY DATEADD(DD, DATEDIFF(DD, 0, dExd_Fecha), 0) 
) m 
    ON e.dExD_Fecha = m.dExd_Fecha_Max 
ORDER BY e.dEXd_Fecha 

생각이 여기 일별로 그룹화 최대 날짜의 하위 쿼리를 만든 다음 기본 테이블에 가입하는 것입니다.

당신이 그들을 제거하기 위해 그 범위를 벗어나는 값을 확인하려면, 당신은 왼쪽 외부를 할 수는 집합에 대해 조인

/** DELETE FROM x **/ 
SELECT * 
FROM (
    SELECT 
    dExd_Fecha, 
    YEAR(dExd_Fecha) AS dExd_Ano, 
    MONTH(dExd_Fecha) AS dExd_Semana, 
    NTILE(10) OVER (ORDER BY dExd_Fecha) AS dExd_Groupo 
    FROM [Existencia_WH_PRISM_BACKUP] 
) x 
LEFT OUTER JOIN ( 
    SELECT MAX(dExd_Fecha) AS dExd_Fecha_Max 
    FROM [PDP].[dbo].[Existencia_WH_PRISM_BACKUP] 
    GROUP BY DATEADD(DD, DATEDIFF(DD, 0, dExd_Fecha), 0) 
) y 
ON x.dExd_Fecha = y.dExd_Fecha_Max 
WHERE 
    x.dExd_Ano = 2010 
    AND x.dExd_Semana = 1 
    AND y.dExd_Fecha_Max IS NULL 
ORDER BY x.dExd_Fecha 

이 SELECT 문은에서 연도와 월 값을 사용 하위 쿼리를 사용하여 일괄 처리 방법을 수행하고 더 적은 양의 레코드를 선택/삭제할 수 있습니다.

원래의 대답은 다음과 같습니다 :

SELECT e.* 
FROM [PDP].[dbo].[Existencia_WH_PRISM_BACKUP] e 
INNER JOIN ( 
    SELECT 
    MAX(dExd_Fecha) AS dExd_Fecha_Max, 

    /** get the year of the last date **/ 
    YEAR(MAX(DATEADD(YY, DATEDIFF(YY, 0, dExd_Fecha), 0))) AS dExd_Ano_Max, 

    /** get the month of the last date **/ 
    MONTH(MAX(DATEADD(MM, DATEDIFF(MM, 0, dExd_Fecha), 0))) AS dExd_Mes_Max, 

    /** get the week of the last date **/ 
    DATEPART(WEEK, MAX(dExd_Fecha)) AS dExd_Semana_Max, 

    /** set a number to divide the total rows into ten groups **/ 
    NTILE(10) OVER (ORDER BY MAX(dExd_Fecha)) AS dExd_Groupo 

    FROM [PDP].[dbo].[Existencia_WH_PRISM_BACKUP] 
    GROUP BY DATEADD(DD, DATEDIFF(DD, 0, dExd_Fecha), 0) 
) m 
    ON e.dExD_Fecha = m.dExd_Fecha_Max 
WHERE 
    m.dExd_Ano_Max = 2010 
    AND m.dExd_Mes_Max = 1 
+0

여기에서 간단한 질문을 드리겠습니다. 1 단계를 모두 처리하지 않으려는 경우 1 주 또는 1 개월 같은 간격을 어떻게 설정할 수 있습니까? 또는 번호 또는 레지스터. – Enrique

+0

예, 하위 쿼리의 새 열을 사용하여이 작업을 수행 할 수 있습니다. 위의 편집. – 8kb

+0

하나의 마지막 질문입니다. 검색 결과와 동일하지 않은 것을 삭제하고 싶다면? 비교에서 오류가 발생했습니다 – Enrique

2

같은 결과를 가져 당신이 할 :

With NumberedData As 
    (
    Select ... 
     , Row_Number() Over (Partition By DateDiff(d, 0, E.dExD_Fetcha) 
           Order By E.dExD_Fetcha Desc) As Num 
    From PDFP.dbo.[Existencia_WH_PRISM_BACKUP] As E 
    ) 
Select ... 
From Data 
Where Num = 1 
+0

나는 토마스 (Thomas) 응답으로 잃어버린 순간이다. 나중에 데이터베이스의 잘못된 데이터를 지우고 싶다. 나중에 병합 할 것이고, "데이터로"수집 한 것이므로 사용 조인이 필요없는 통합을 만들 수있다. – Enrique

+0

@Enrique - 공통 테이블 식을 사용하고 있습니다. 나는 CTE "데이터"라는 이름을지었습니다. CTE (이 경우 "NumberedData")에 대한 더 나은 이름을 제공하기 위해 내 게시물을 개정했습니다. 간단히 말해서, 매주 시스템 번호가 매겨져 매일 번호가 다시 매겨지며 최신 시간이 가장 낮은 번호 (예 : 최신 시간은 1, 다음 최신 등은 2)가됩니다. – Thomas

0

나는 토마스가 게시 커서를 사용하지 않고도 쿼리 이후로 그와 함께 갈 것 솔루션 거의 항상 바람직 하나를 사용 하나입니다 좋아한다. (SQL은 SET 논리를 위해 만들어 졌기 때문에 항상 최선을 다하는 것이 더 효율적일 것입니다.)

또한 동시에 저장되는 한 여러 행을 필요로한다고했습니다 . Thomas 솔루션에 쓰여진 CTE 표현은 마지막 단 하나만으로 충분할 수 있습니다. 그렇지 않으면 자신의 솔루션을 쉽게 수정할 수 있습니다.

다음은 커서 솔루션에 대한 호기심이 있기 때문에 다음과 같습니다. 나는 그것을 사용해서는 안된다는 조언을하지만, 가능하다는 것을 알아야한다.

나중에 분석을 위해 결과를 유지하려면 테이블 변수 대신 실제 테이블을 사용하십시오.

DECLARE @t1 TABLE (DtTm datetime) 

DECLARE @Dt datetime   
DECLARE c CURSOR FOR 
    SELECT CONVERT(datetime, CONVERT(char(11), dExD_Fecha, 113)) 
    FROM [PDP].[dbo].[Existencia_WH_PRISM_BACKUP] 
    GROUP BY CONVERT(char(11), dExD_Fecha, 113) 

OPEN c 
FETCH NEXT FROM c INTO @Dt 
WHILE @@FETCH_STATUS = 0 
BEGIN 
    INSERT INTO @t1 
    SELECT dExD_Fecha -- add any other fields you care to capture here and above to the table definition 
    FROM [PDP].[dbo].[Existencia_WH_PRISM_BACKUP] 
    WHERE dExD_Fecha = (
     SELECT MAX(dExD_Fecha) 
     FROM [PDP].[dbo].[Existencia_WH_PRISM_BACKUP] 
     WHERE CONVERT(datetime,CONVERT(char(11), dExD_Fecha, 113)) = @Dt) 
    FETCH NEXT FROM c INTO @Dt 
END 

CLOSE c 
DEALLOCATE c 

SELECT * FROM @t1 
관련 문제