2017-10-23 2 views
3

레코드를 선택하기 위해 지난 3 년 동안 매월 최대 받기 사용자가 전화를 걸 때마다에 날짜 시간 및 사용자 ID를 추가하여, 우리는 우리가 매번 사용자처럼 기록되어 2012 년</p> <p>이 전화를 만드는 MS SQL 서버를 사용하는 달

이제는 사용자가 생성 한 이후 매월 최상, 매주, 매일 기록을 계산해야합니다.

의미, 나는 어떤 사용자든지 창조부터 주어진 달 동안 가지고 있던 가장 높은 매달 조사를 산출 할 필요가있다. 그래서 기록적인 월별 집계와 그 집의 이름.

나는 그걸 위해 최선을 다할 수 있을지 잘 모르겠다. 이것이 지금 내가 만든 것이며, 그렇게 할 수있는 더 효과적인 방법이 있는지 궁금해하고있다.

다음은 샘플이 업데이트 된 버전입니다.

DECLARE @id int, @mr int 
DECLARE @first datetime, @last datetime 
DECLARE @name nvarchar(60) 

DECLARE @UserTable TABLE(
    ID int, 
    Name nvarchar(60) 
) 

INSERT INTO @UserTable (ID, Name) VALUES (1, 'Tester'); 
INSERT INTO @UserTable (ID, Name) VALUES (2, 'Dummy'); 
INSERT INTO @UserTable (ID, Name) VALUES (3, 'User'); 


DECLARE @SampleTable TABLE(
    A_Termin_AE int, 
    A_Termin_Status int, 
    A_Termin_Set_Date datetime 
) 

INSERT INTO @SampleTable (A_Termin_AE, A_Termin_Status, A_Termin_Set_Date) VALUES (1, 603, CAST('20090525' AS Datetime)); 
INSERT INTO @SampleTable (A_Termin_AE, A_Termin_Status, A_Termin_Set_Date) VALUES (1, 601, Cast('20090512' AS Datetime)); 
INSERT INTO @SampleTable (A_Termin_AE, A_Termin_Status, A_Termin_Set_Date) VALUES (1, 603, Cast('20090525' AS Datetime)); 
INSERT INTO @SampleTable (A_Termin_AE, A_Termin_Status, A_Termin_Set_Date) VALUES (1, 603, Cast('20100803' AS Datetime)); 
INSERT INTO @SampleTable (A_Termin_AE, A_Termin_Status, A_Termin_Set_Date) VALUES (1, 603, Cast('20100805' AS Datetime)); 
INSERT INTO @SampleTable (A_Termin_AE, A_Termin_Status, A_Termin_Set_Date) VALUES (1, 603, Cast('20100817' AS Datetime)); 
INSERT INTO @SampleTable (A_Termin_AE, A_Termin_Status, A_Termin_Set_Date) VALUES (1, 601, Cast('20110521' AS Datetime)); 


INSERT INTO @SampleTable (A_Termin_AE, A_Termin_Status, A_Termin_Set_Date) VALUES (2, 601, Cast('20090501' AS Datetime)); 
INSERT INTO @SampleTable (A_Termin_AE, A_Termin_Status, A_Termin_Set_Date) VALUES (2, 603, Cast('20090502' AS Datetime)); 
INSERT INTO @SampleTable (A_Termin_AE, A_Termin_Status, A_Termin_Set_Date) VALUES (2, 603, Cast('20100815' AS Datetime)); 
INSERT INTO @SampleTable (A_Termin_AE, A_Termin_Status, A_Termin_Set_Date) VALUES (2, 603, Cast('20110501' AS Datetime)); 
INSERT INTO @SampleTable (A_Termin_AE, A_Termin_Status, A_Termin_Set_Date) VALUES (2, 603, Cast('20110505' AS Datetime)); 
INSERT INTO @SampleTable (A_Termin_AE, A_Termin_Status, A_Termin_Set_Date) VALUES (2, 603, Cast('20110508' AS Datetime)); 
INSERT INTO @SampleTable (A_Termin_AE, A_Termin_Status, A_Termin_Set_Date) VALUES (2, 603, Cast('20110510' AS Datetime)); 
INSERT INTO @SampleTable (A_Termin_AE, A_Termin_Status, A_Termin_Set_Date) VALUES (2, 603, Cast('20110514' AS Datetime)); 


INSERT INTO @SampleTable (A_Termin_AE, A_Termin_Status, A_Termin_Set_Date) VALUES (3, 603, Cast('20120503' AS Datetime)); 
INSERT INTO @SampleTable (A_Termin_AE, A_Termin_Status, A_Termin_Set_Date) VALUES (3, 603, Cast('20120508' AS Datetime)); 
INSERT INTO @SampleTable (A_Termin_AE, A_Termin_Status, A_Termin_Set_Date) VALUES (3, 603, Cast('20120510' AS Datetime)); 
INSERT INTO @SampleTable (A_Termin_AE, A_Termin_Status, A_Termin_Set_Date) VALUES (3, 603, Cast('20120514' AS Datetime)); 
INSERT INTO @SampleTable (A_Termin_AE, A_Termin_Status, A_Termin_Set_Date) VALUES (3, 603, Cast('20120520' AS Datetime)); 
INSERT INTO @SampleTable (A_Termin_AE, A_Termin_Status, A_Termin_Set_Date) VALUES (3, 601, Cast('20130701' AS Datetime)); 
INSERT INTO @SampleTable (A_Termin_AE, A_Termin_Status, A_Termin_Set_Date) VALUES (3, 603, Cast('20130703' AS Datetime)); 

DECLARE @TempTable TABLE(
    ID int, 
    UserID int, 
    Name nvarchar(60), 
    Record int, 
    Datum datetime 
) 

INSERT INTO @TempTable (ID, UserID, Name, Record, Datum) VALUES (1, 0, '', 0, GETDATE()); 

SET @first = CAST('20080101' AS Datetime); 

WHILE @first < GETDATE() 
BEGIN 

    SET @first = dateadd(month, 1, @first) 
    SET @last = DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@first)+1,0)); 

    DECLARE User_Cur CURSOR 
     FOR SELECT tu.Id, tu.Name FROM @UserTable tu 
     OPEN User_Cur; 

      FETCH NEXT FROM User_Cur INTO @id, @name; 

      WHILE @@FETCH_STATUS = 0 
      BEGIN  
       SET @mr = (SELECT COUNT(t.A_Termin_Set_Date) 
          FROM @SampleTable t 
          WHERE t.A_Termin_AE = @id 
           AND t.A_Termin_Status = 603 
           AND t.A_Termin_Set_Date BETWEEN @first AND @last); 

       IF (SELECT Record FROM @TempTable WHERE ID = 1) < @mr 
       BEGIN 
        UPDATE @TempTable 
         SET UserID = @id, 
          Name = @name, 
          Record = @mr, 
          Datum = @first 
        WHERE ID = 1; 
       END 

      FETCH NEXT FROM User_Cur INTO @id, @name; 
      END 

     CLOSE User_Cur; 
    DEALLOCATE User_Cur; 

END 

SELECT * FROM @TempTable; 

그래서 한 달에서 만든 대부분의 통화에 사용자는 다음과 같습니다 : '더미'5 개 레코드와

이 월별 기록입니다 (I 날짜 변경을 적용, 난이 도움이되기를 바랍니다) 2011 년 5 월

이에 대한 도움과 제안에 감사드립니다.

+1

주의를 기울이려면 사용하는 dbms에 태그를 지정하십시오. (해당 코드는 제품마다 다릅니다.) – jarlh

+0

창 작업 기능 ('over'절)을 살펴보십시오. 원시 날짜와 예상 결과의 짧은 예를 보여 주면보다 간결한 방식으로 질문을 표현하는 데 도움이 될 수 있습니다. – Jan

+0

** [EDIT] ** ** [샘플 데이터] (http : //plaintexttools.github. io/plain-text-table /) 및 해당 데이터를 기반으로 예상되는 출력을 표시합니다. [** 포맷 된 텍스트 **] (http://stackoverflow.com/help/formatting)하시기 바랍니다. [** 스크린 샷 없음 **] (http://meta.stackoverflow.com/questions/285551/why-may -i-not-upload-images-of-code-on-so-ask-a-question/285557 # 285557). ** [편집] ** 귀하의 질문 - 코멘트 **에 ** 코드 ** 또는 추가 정보를 게시하지 마십시오. –

답변

0

좋아, 방금 친구와 채팅을했고, 그는 나에게이 일을위한 매우 간단하고 빠르고 쉬운 방법을 설명했다. 경우 사람이 같은 문제가 건너 온다, 여기에 대답 :

SELECT TOP(1) COUNT(t.A_Termin_AE) AS Record 
     , tu.Name 
     , DATEADD(MONTH, DATEDIFF(MONTH, 0, t.A_Termin_Set_Date), 0) AS Datum 
    FROM @SampleTable t 
     JOIN @UserTable tu ON tu.Id = t.A_Termin_AE 
      WHERE t.A_Termin_Status = 603 
       GROUP BY tu.Name, DATEADD(MONTH, DATEDIFF(MONTH, 0, t.A_Termin_Set_Date), 0) 
        ORDER BY Record DESC; 

다시 한번 감사 모든 도움!

+0

동일한 높은 가치를 가진 몇 달이 있으면 어떻게됩니까? –

1

샘플 데이터에는 동일한 최대 수의 다른 달에 2 명의 사용자가 포함되어 있습니다. 그런데 왜 당신은 단지 1을 나열 할까? 어떻게 당신이 1 개 이상이 알고있는 것, 그것은 수 4 2 37

SELECT 
     Name 
     , Mnth 
     , Record 
     , dense_rank() over(ORDER BY record DESC) RNK 
FROM (
     SELECT 
       Name 
       , Mnth 
       , Record 
       , dense_rank() over(ORDER BY record DESC) RNK 
     FROM (
       SELECT 
         tu.Name 
         , DATEADD(MONTH, DATEDIFF(MONTH, 0, t.A_Termin_Set_Date), 0) AS Mnth 
         , COUNT(t.A_Termin_AE) AS Record 
       FROM @SampleTable t 
       JOIN @UserTable tu ON tu.Id = t.A_Termin_AE 
       WHERE t.A_Termin_Status = 603 
       GROUP BY tu.Name, DATEADD(MONTH, DATEDIFF(MONTH, 0, t.A_Termin_Set_Date), 0) 
     ) d1 
    ) d2 
WHERE rnk = 1 
ORDER BY Mnth DESC, Name 

결과 :

Name   Mnth   Record RNK 
------- --------------------- -------- ----- 
    User 01.05.2012 00:00:00  5  1 
    Dummy 01.05.2011 00:00:00  5  1 

가 참조 : http://rextester.com/DORH41455

0

것은 내가 @ 동의해야 이미 Used_By_되었습니다. 나는 여러 CTE 방식과 비슷한 짓을 중첩 SQL 문없이

: 나는 그것도 좋을 것이다 생각

name month     record rank 
Dummy 2011-05-01 00:00:00.000 5  1 
User 2012-05-01 00:00:00.000 5  1 

:

을 ...

;WITH counting_records AS (
      SELECT tu.name, 
        DATEADD(MONTH, DATEDIFF(MONTH, 0, st.A_Termin_Set_Date), 0) AS month, 
        COUNT(st.A_Termin_AE) AS record 
       FROM @SampleTable st 
       INNER JOIN @UserTable tu ON tu.Id = st.A_Termin_AE 
       WHERE st.A_Termin_Status = 603 
       GROUP BY tu.Name, DATEADD(MONTH, DATEDIFF(MONTH, 0, st.A_Termin_Set_Date), 0) 
), get_rank (name, month, record, rank) AS (
      SELECT cr.name, 
       cr.month, 
       cr.record, 
       DENSE_RANK() OVER(ORDER BY cr.record DESC) AS rank 
      FROM counting_records AS cr 
      ) 

-- getting the highest count (lowest rank) 
    SELECT get_rank.name, 
      get_rank.month, 
      get_rank.record, 
      get_rank.rank 
    FROM get_rank 
    WHERE get_rank.rank = 1 
    ORDER BY get_rank.month 

하는 결과를 갖는 설명하기 위해 DENSE_RANK() OVER(ORDER BY cr.record DESC) AS rank.

DENSE_RANK()

는 ... 순위에서 틈새없이 결과 집합의 파티션 내에서 행의 순위를 돌려줍니다.

Syntax: `DENSE_RANK () OVER ([ <partition_by_clause> ] <order_by_clause>)`