【问题标题】:Join two tables to get counts different dates加入两个表以获取不同日期的计数
【发布时间】:2015-01-09 17:17:03
【问题描述】:

我有一个带有列的表 A:

id, transactiondate, pointsordered

表 B

id,redemptiondate,pointsused

表 C

作为

id,joindate

我想要什么

某个日期范围需要所有数据,比如 YYYY-MM-DD 中的 2014-01-01 到 2014-02-01

  • 按日期计算的总 ID 数(表 a 中的 ID 数)
  • 在该日期进行第一笔交易的账户数

  • 按日期排序的总分(表 a 中的总分)

  • 在该日期赎回的帐户数(表 b 中的 id 数)
  • countofpointsued 在那个日期(表 b 中的点总和)

  • 按日期加入的新客户

我知道 id 是表 b 和表 c 的外键,但我如何确保我匹配日期?

例如,如果我按日期加入,例如 a.transactiondate=b.redemption.date,它会为我提供在该日期进行交易并在该日期赎回的所有客户。

我想要计算在该日期进行交易的所有客户以及在该日期兑换的客户(无论他们何时进行交易)

这是我尝试过的

select count( distinct a.id) as noofcustomers, sum(a.pointsordered), sum(b.pointsused), count(distinct b.id)
from transaction as a join redemption as b on a.transactiondate=b.redemptiondate
where a .transactiondate between '2014-01-01' and '2014-02-01' 
group by a.transactiondate,b.redemptiondate

【问题讨论】:

  • 首先为什么你的表叫保留字?如果您还有另一个带有整数的表(您可以将该天数添加到开始日期)或仅包含日期,您将能够做得更好。然后将您的汇总(分组)结果加入到该起始表中。

标签: sql sql-server join count


【解决方案1】:

我会先按表格对数据进行分组,然后再按日期加入结果。您不应该使用内部联接,因为如果一侧没有匹配的记录(例如在给定日期没有交易但赎回),您可能会丢失数据。如果您有该范围内的日期列表会有所帮助。如果没有,您可以使用 CTE 构建一个。

declare @from date = '2014-01-01'
declare @to date = '2014-02-01'
;
with dates as
(
  select @from as [date]
  union all
  select dateadd(day, [date], 1) as d from dates where [date] < @to
)
, orders as
(
  select transactiondate as [date], count(distinct id) as noofcustomers, sum(pointsordered) as pointsordered
  from [transaction]
  where transactiondate between @from and @to
  group by transactiondate 
)
, redemptions as
(
  select redemptiondate as [date], count(distinct id) as noofcustomers, sum(pointsused) as pointsused
  from [redemption]
  where redemptiondate between @from and @to
  group by redemptiondate 
)
, joins as
(
  select joindate as [date], count(distinct id)  as noofcustomers
  from [join]
  where joindate between @from and @to
  group by joindate
)
, firsts as
(
  select transactiondate as [date], count(distinct id) as noofcustomers
  from [transaction] t1
  where transactiondate between @from and @to
  and not exists (
    select * from [transaction] t2 where t2.id = t1.id and t2.transactiondate < t1.transactiondate)
  group by transactiondate 
)
select 
  d.[date], 
  isnull(o.noofcustomers,0) as noofcustomersordered,
  isnull(o.pointsordered,0) as totalpointsordered,
  isnull(f.noofcustomers,0) as noofcustomersfirsttran,
  isnull(r.noofcustomers,0) as noofcustomersredeemed,
  isnull(r.pointsused,0) as totalpointsredeemed,
  isnull(j.noofcustomers,0) as noofcustomersjoined  
from dates d
left join orders o on o.[date] = d.[date]
left join redemptions r on r.[date] = d.[date]
left join joins j on j.[date] = d.[date]
left join firsts f on f.[date] = d.[date]

请注意,我没有运行查询,因此它们可能是错误的,但我认为总体思路很清楚。

【讨论】:

    猜你喜欢
    • 2013-11-05
    • 1970-01-01
    • 1970-01-01
    • 2020-06-23
    • 2020-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多