2017-12-22 24 views
1

보안 변경 감사 테이블 AdvApp.vSecurity_Hist h에서 시간 경과에 따른 금융 증권 변경 내용을 추적하기 위해 시계열을 만들려고합니다. 심볼, ISIN, SEDOL, CUSIP 등의 고유 한 보안 식별자에 대해 MIN 날짜가있는 행만보고 싶습니다. 이 중 하나가 변경된 행만보고 싶습니다. 이러한 변경은 회사 재구성으로 인한 것이지만 시스템에서 생성 된 SecurityID는 변경되지 않습니다. 고유 한 보안 ID 당 다른 열의 변경 만 원합니다. 다음은 합법적으로 3 번 변경된 보안 및 변경된 날짜의 예입니다. 여기에 쿼리 결과에 아무런 문제가 없습니다.SQL Server 2012 최소 행 실패로 축소

변경 사항이있는 정규 시간 계열.

같은 날에 여러 변경 사항이있는 경우 최대 시간이있는 행이 선택됩니다. 나는 일일 변화가 아니라 내적인 변화를 찾고 있습니다.

SecurityID MinDate CUSIP ISIN SEDOL Symbol SecurityCount 
5156 2011-10-22 61745P635   iqc 3 
5156 2012-01-31 46130M107   iqc 3 
5156 2012-09-12 46130m107   iqcoldx 3 

다음은 내 쿼리를 위반하는 문제가있는 시계열의 원시 데이터 예제입니다. 참고 행 10에 CUSIP 필드의 값이 누락되어 있습니다. CUSIP이 없지만 동일한 CUSIP 값이 빈 필드를 앞뒤로 통과하면 공백 필드가 합법이 아니므로 규칙이 적용됩니다. 해당 필드의 선행 및 후행 값. 당신이 볼 수 있듯이 CUSIP 값은 다음이 문제가 데이터를 기반으로 내 쿼리의 결과 행에서 원시 데이터

SecurityID CUSIP ISIN SEDOL Symbol OptionSymbol AuditEventTime 
5060 233809201   fduxx  2011-10-22 00:12:31.310 
5060 233809201   fduxx  2012-03-21 19:33:41.387 
5060 233809201   fduxx  2012-03-21 21:40:05.813 
5060 233809201   fduxx  2012-03-30 15:00:45.243 
5060 233809201   fduxx  2012-04-04 11:31:59.280 
5060 233809201   fduxx  2012-05-15 09:19:38.360 
5060 233809201   fduxx  2012-05-15 10:04:10.597 
5060 233809201   fduxx  2012-07-03 15:54:41.043 
5060 233809201   fduxx  2013-04-04 18:25:27.253 
5060    fduxx  2013-09-26 09:45:00.137 
5060 233809201   fduxx  2013-10-01 13:03:59.277 
5060 233809201   fduxx  2016-12-02 18:52:53.093 
5060 233809201   fduxx  2017-10-06 08:43:58.717 

에서 설정 11

문제를 다시 시작합니다. 쿼리는 변경 사항의 최소 날짜를 그룹화하여 행 1과 행 9를 선택하지만 일부 문제를 일으키는 행 11-13은 무시합니다.

쿼리 결과입니다.

필자의 규칙에 따라 빈 칸 앞에 두 번째 행을 넣고 싶지는 않습니다. 앞뒤에있는 행의 값이 모든 필드에서 일치하기 때문입니다. 내가 리드를 사용하여 논리를 활용에 대해 생각하고 지연하고

SecurityID MinDate CUSIP ISIN SEDOL Symbol SecurityCount 
5060 2011-10-22 233809201   fduxx 2 
5060 2013-09-26    fduxx 2 

곳이 빈 행하지만지도하고 값이 서로 (시간 제외)과 일치 지연하는 경우 다음 빈 행을 주도 CUSIP 값을 넣습니다. 그런 다음 SecurityID 5060이있는 데이터 집합을 하나의 행으로 축소 할 수 있습니다. 내 파티션이나 내 쿼리를 변경하여 최종 행 11-13이 실제로 세 번째 계열임을 인식 할 수 있도록이 작업을 수행해야한다고 생각합니다. 현재 값은 공백 앞에있는 데이터와 일치하므로 최종 행은 무시됩니다. 따라서 해당 집합의 최소 날짜가 아닙니다. 여기에 내 SQL 쿼리입니다. 나는 다음 알고 싶습니다 :

1)How can I make the query result produce three rows for SecurityID 5060? (Make it consider the data that comes after the blank as it's own row) 
2)where and how in the query should I then apply Lead and Lag to help fill in the blank and then collapse the result into a single row? 

감사합니다

나의 현재 쿼리

WITH DATA AS 
(
SELECT 
b.SecurityID, 
MIN(b.AuditEventDate)MinDate, 
b.CUSIP, 
b.ISIN, 
b.SEDOL, 
b.Symbol, 
COUNT(b.SecurityID) OVER (PARTITION BY b.SecurityID)SecurityCount 
FROM 
(
SELECT a.*, 
MAX(a.AuditEventTime) OVER (PARTITION BY a.SecurityID,a.AuditEventDate) MaxTime 
FROM 
(
SELECT distinct 
h.SecurityID 
,h.AuditEventTime 
,CAST(h.AuditEventTime AS DATE)AuditEventDate 
,CASE WHEN ISNULL(h.OptionSymbol,'') <> '' THEN h.OptionSymbol ELSE h.Symbol END Symbol 
,h.CUSIP 
,h.SEDOL 
,h.ISIN 
FROM APXFirm.AdvApp.vSecurity_Hist h 
WHERE 1 = 1 
AND (LEN(h.CUSIP) = 9 OR ISNULL(h.CUSIP,'') = '') 
AND (LEN(h.SEDOL) = 7 OR ISNULL(h.SEDOL,'') = '') 
AND (LEN(h.ISIN) = 12 OR ISNULL(h.ISIN,'') = '') 
AND h.SecurityID = 5060 
)a 
)b 
WHERE b.AuditEventTime = b.MaxTime 
GROUP BY b.SecurityID, 
     b.CUSIP, 
     b.ISIN, 
     b.SEDOL, 
     b.Symbol 
) 
SELECT * FROM Data 
WHERE DATA.SecurityCount > 1 
ORDER BY Data.SecurityID,MINDate 

답변

1
당신은 가능한 한 빨리 (소스에서 그 NULL 값을 "수정"해야합니다

) 그렇지 않으면 그룹화 후에 신뢰할 수있는 "이전/다음"행 관계를 사용할 수 없습니다

SELECT 
     b.SecurityID 
     , MIN(b.AuditEventDate)        mindate 
     , b.CUSIP 
     , b.ISIN 
     , b.SEDOL 
     , b.Symbol 
     , COUNT(b.SecurityID) OVER (PARTITION BY b.SecurityID) securitycount 
    FROM (
     SELECT 
       a.* 
      , MAX(a.AuditEventTime) OVER (PARTITION BY a.SecurityID, a.AuditEventDate) maxtime 
     FROM (
       SELECT DISTINCT /* but I doubt that distinct does anything useful */ 
        h.SecurityID 
        , h.AuditEventTime 
        , CAST(h.AuditEventTime AS date)             auditeventdate 
        , CASE WHEN ISNULL(h.OptionSymbol, '') <> '' THEN h.OptionSymbol ELSE h.Symbol END symbol 
        , case when h.CUSIP IS NULL and lag(h.CUSIP,1) over(order by AuditEventTime) 
               = lead(h.CUSIP,1) over(order by AuditEventTime) 
         then lead(h.CUSIP,1) over(order by AuditEventTime) 
         else h.CUSIP 
        end as CUSIP 
        , h.SEDOL 
        , h.ISIN 
       FROM vSecurity_Hist h 
       /* where clause needed here */ 
     ) a 
) b 
    WHERE b.AuditEventTime = b.MaxTime 
    GROUP BY 
     b.SecurityID 
     , b.CUSIP 
     , b.ISIN 
     , b.SEDOL 
     , b.Symbol 

Demo

+0

지금 체크 아웃. –

+0

작동하는 것 같습니다. 사실 Leadit and Lag의 순서대로 AuditEventTime에 securityID를 추가해야했습니다. 왜냐하면 실제로 데이터에 많은 유가 증권이 있기 때문입니다.또한 데이터 CUSIP 실제로 = ''NULL이 아니지만 쉽게 해결할 수 있습니다. –