【问题标题】:SQL - Creating counts for 1st, 2nd, 3rd occasion in a listSQL - 在列表中为第 1 次、第 2 次、第 3 次创建计数
【发布时间】:2014-08-27 15:54:51
【问题描述】:

我有一个带有日期戳和 ID 号的数据集,如图所示:

Date_Stamp  | ID
2013-07-17  | ID1
2013-07-17  | ID1
2013-08-19  | ID1
2013-08-19  | ID2

根据这些数据,我需要填充一个包含以下字段的表:日期、ID、First_attempt、Second_Attempt、Third_Attempt、Total_Attempts。

使用该数据,文件将如下所示:

Date | ID | First_attempt | Second_Attempt | Third_Attempt | Total_Attempts
2013-07-17 | ID1 | 1 | 1 | 0 | 2
2013-08-19 | ID1 | 0 | 0 | 1 | 1
2013-08-19 | ID2 | 1 | 0 | 0 | 1

我已经能够使用此代码进行第一次尝试:

Select  min(date_stamp) as date_stamp,
        ID,
        1 as First_attempt,
        0 as Second_Attempt,
        0 as Third_Attempt,
        0 as Total_Attempts
from Table
group by ID

以及使用此代码的总尝试次数(每天):

Select  date_stamp as date_stamp,
        ID,
        0 as First_attempt,
        0 as Second_Attempt,
        0 as Third_Attempt,
        count(ID) as Total_Attempts
from Table
group by date_stamp, ID

有人可以帮忙编写第二次和第三次尝试的脚本吗?

【问题讨论】:

  • 这些尝试是在您的表中还是您只是硬编码值?
  • 我正在尝试根据日期和 ID 出现的次数得出尝试。 ID 是一个电话号码,我正在尝试确定拨打同一个号码的次数。
  • 你需要三列位类型(真/假)还是你可以只用一列类型 int 替换并增加总尝试次数?
  • 很遗憾,上述列是必需的

标签: sql sql-server count counter


【解决方案1】:

试试这个:

;WITH CTE AS
(
    SELECT  *,
            RN = ROW_NUMBER() OVER(PARTITION BY Date_Stamp, ID ORDER BY Date_Stamp),
            Total = COUNT(*) OVER(PARTITION BY Date_Stamp, ID)
    FROM YourTable
)
SELECT  Date_Stamp AS [Date],
        ID,
        MAX(CASE WHEN RN = 1 THEN 1 ELSE 0 END) First_attempt,
        MAX(CASE WHEN RN = 2 THEN 1 ELSE 0 END) Second_attempt,
        MAX(CASE WHEN RN = 3 THEN 1 ELSE 0 END) Third_attempt,
        MAX(Total) Total_Attempts
FROM CTE
GROUP BY Date_Stamp,
         ID;

Here is 一个带有演示的 sqlfiddle。

结果是:

╔════════════╦═════╦═══════════════╦════════════════╦═══════════════╦════════════════╗
║    DATE    ║ ID  ║ FIRST_ATTEMPT ║ SECOND_ATTEMPT ║ THIRD_ATTEMPT ║ TOTAL_ATTEMPTS ║
╠════════════╬═════╬═══════════════╬════════════════╬═══════════════╬════════════════╣
║ 2013-07-17 ║ ID1 ║             1 ║              1 ║             0 ║              2 ║
║ 2013-08-19 ║ ID1 ║             1 ║              0 ║             0 ║              1 ║
║ 2013-08-19 ║ ID2 ║             1 ║              0 ║             0 ║              1 ║
╚════════════╩═════╩═══════════════╩════════════════╩═══════════════╩════════════════╝

【讨论】:

  • 这更接近我所拥有的,但第二条记录应该显示第三次尝试而不是第一次尝试,因为该 ID 之前已经尝试过两次(7/17)
  • @NRud 然后如果有第四次尝试会发生什么,应该有另一列吗?因为那会改变很多答案
  • 第四次尝试和任何进一步的尝试都将被计入total_attempts。
  • @Anon 是的,我看错了第二行。无论如何,我可以通过删除PARTITION BY 中的Date_Stamp 来修复我的答案,但是现在没有正确的答案了
【解决方案2】:
 ;WITH TEMPTABLE AS(
    SELECT  DATE_STAMP,
            ID,
            ROW_NUMBER() OVER( PARTITION BY ID ORDER BY DATE_STAMP ) AS ROWNUMBER,
            Count(ID) OVER(PARTITION BY Date_Stamp, ID) as countID
    FROM #temp)
    SELECT DATE_STAMP,
            ID,
            MAX(CASE WHEN ROWNUMBER = 1 THEN 1 ELSE 0 END )AS FIRST_ATTEMPT,
            MAX(CASE WHEN ROWNUMBER = 2 THEN 1 ELSE 0 END) AS SECOND_ATTEMPT,
            MAX(CASE WHEN ROWNUMBER = 3 THEN 1 ELSE 0 END) AS THIRD_ATTEMPT,
            MAX(countID) Total_Attempts
     FROM TEMPTABLE 
     GROUP BY DATE_STAMP,ID

【讨论】:

  • 太完美了!谢谢!
【解决方案3】:

你需要三列位类型(真/假)还是你可以只用一列类型int替换并增加总尝试次数?

那么你可以使用下面的查询

Select SUM(Total_Attempts), date_stamp
FROM Table
GROUP BY date_stamp

编辑:在更新 Total_Attemps 列之前,检查 Total_Attempts 是否

【讨论】:

    【解决方案4】:

    我已经在sql中使用switch语句回答了这个问题 希望这有效

    SELECT   Date_stamp, "Third Attempt" = 
      CASE 
         WHEN count(ID) =  3 THEN '1'
         ELSE '0'
      END
    FROM tablename
    GROUP BY Date_stamp;
    

    【讨论】:

    • 谢谢!我曾尝试过类似的事情,但仍然不太正确。如果一天内尝试了 3 次,count(ID) = 3 将发生,即使跨日期,我也需要确定第三次尝试。
    【解决方案5】:
    WITH t AS (
      SELECT
        [date]
       ,[id]
       ,ROW_NUMBER() OVER (PARTITION BY [ID] ORDER BY [date]) [num_calls]
       ,COUNT(*) OVER (PARTITION BY [ID] ORDER BY [date]) [Total_Attempts]
      FROM @MyTable
    )
    SELECT
      [date]
     ,[id]
     ,[1] AS [First_Attempt]
     ,[2] AS [Second_Attempt]
     ,[3] AS [Third_Attempt]
     ,[Total_Attempts]
    FROM t
    PIVOT(COUNT([num_calls]) FOR [num_calls] IN ([1],[2],[3])) p
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-05
      • 1970-01-01
      • 1970-01-01
      • 2014-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多