【问题标题】:TSQL: How to get distinct values over a period of time but not within my group byTSQL:如何在一段时间内但不在我的组内获得不同的值
【发布时间】:2014-10-09 01:58:43
【问题描述】:

我不确定标题是否合适,但我想做的是创建一个聚合表,其中包含按 小时 细分的统计信息,但我需要一段时间内的不同值到那个小时。示例:

ID  Group  Date 
-------------------------
1     1    1/1/2014 11:00
2     1    1/1/2014 11:00
1     1    1/1/2014 11:00
3     1    1/1/2014 11:00
3     2    1/1/2014 12:00
1     2    1/1/2014 12:00
1     1    1/1/2014 12:00
2     1    1/1/2014 12:00
4     1    1/1/2014 12:00

结果是:

Count    Group    Hour
------------------------
  3        1      11:00
  2        2      12:00
  1        1      12:00

请注意 ID 1 如何在第 1 组中多次出现,但在多个小时内仅计数一次,但按小时分组。我的问题是我在那个小时内变得独一无二,但如果另一个 1 发生在另一个小时内,它就会被计算在内。

这是我的查询:

MERGE dbo.tblStatsHourlyDomainCampaign AS Target
USING (SELECT   
          (LEFT(CONVERT(VARCHAR,sl.CreateDate,120),13) + ':00') as ReportDay, 
          em.DomainID, COUNT(distinct sl.EmailID) as Opens, sl.QueueID 
       FROM dbo.tblEmail em 
       INNER JOIN dbo.tblImpressionLog sl ON em.EmailID = sl.EmailID
       WHERE sl.CreateDate >= '10/1/2014' AND sl.CreateDate < '10/10/2014'
       GROUP BY LEFT(CONVERT(VARCHAR,sl.CreateDate,120),13) + ':00', em.DomainID , sl.QueueID) AS Source 
    ON (target.domainid = source.domainid AND target.ReportDay = source.ReportDay 
        AND target.QueueID = source.QueueID)

WHEN NOT MATCHED BY TARGET AND source.DomainID IS NOT NULL
  THEN 
    INSERT (DomainID, ReportDay, Opens, QueueID) 
    VALUES (source.DomainID, source.ReportDay, source.Opens, source.QueueID)

WHEN MATCHED
  THEN 
    UPDATE 
       SET target.Opens = source.Opens;

【问题讨论】:

  • 请将示例数据列名称更新为查询中使用的确切名称。如果我猜对了,你只需要从 groupby 中删除一列

标签: sql-server tsql datetime sum distinct


【解决方案1】:
SELECT Count(1),
       [group],
       cast(date as time)
FROM  (SELECT Row_number()
                OVER (
                  partition BY id, [group]
                  ORDER BY id, date, [group]) row_num,
              id,
              [group],
              date
       FROM   #temp) a
WHERE  row_num = 1
GROUP  BY [group],
          date 

【讨论】:

    【解决方案2】:

    根据您的示例数据和结果,您可以使用按组分区的 row_number 过滤 id。让id只存在于一组中的第一个小时。

    with t1 as
    (
    select row_number() over (partition by id, [group]  order by createdate) as rowid
           ,id, [group], createdate
    from your_table
    )
    select count(*),[group],left(convert(VARCHAR,createdate,120),13)
    from t1
    where rowid=1
    group by [group],left(convert(VARCHAR,createdate,120),13)
    

    SQL FIDDLE DEMO

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-04-18
      • 2021-11-18
      • 1970-01-01
      • 2012-11-28
      • 1970-01-01
      • 2021-07-06
      • 2021-03-27
      相关资源
      最近更新 更多