【问题标题】:How can I Compare two tables without relationship (1 table with 40k records and the other one with 7k records)?如何比较没有关系的两张表(一张有 40k 条记录,另一张有 7k 条记录)?
【发布时间】:2018-08-01 04:14:20
【问题描述】:

我尝试使用 Cross Join,但运行需要 5 分钟,还有其他方法吗? 笔记: 我正在比较日期和 Int 字段,表 1 包含来自系统的记录,表 2 存储工作日历日期。 SQL 服务器。

B FILE

C FILE

Trying to achieve

SampleCode

【问题讨论】:

  • 请创建一个非常简单的示例数据集并将其添加到帖子中以说明您的问题以及您希望实现的目标。
  • 比较的是什么?仅仅因为关系不存在并不意味着您不能在您认为应该匹配的列上执行full outer join...它只会比存在关系时慢...您也可以使用 set based operations,例如 except 或 intersect... 就目前而言,这个问题太模糊,无法提供任何真正的帮助。
  • jcaceres,请设置一些示例数据并解释所有问题。昨天您发布了一些查询,但没有更多的范围和对总体目标的理解以及数据的外观我们只是在猜测您要完成的工作,请给我们一些数据和表定义-关系是什么在 int 和 date 列之间?
  • 好的,请稍等......
  • 取决于你所说的“比较”。

标签: sql-server date ssis case-when cross-join


【解决方案1】:

这并不容易,但这是一个可行的解决方案。将来尝试在您的问题中使用这种类型的代码,以便我们可以专注于查询和解决方案。我已经编辑了您的一些日期以使示例正常工作。

编辑:新代码

declare @cal table (
    calID int not null
,   date_ date not null
,   isWeekday bit not null
,   isHoliday bit not null
,   year_  int not null
);

insert into @cal (calID, date_, isWeekday, isHoliday, year_)
select 1,    '1-Jan-2010',  1,  1,  2010 union all
select 2,    '2-Jan-2010',  0,  0,  2010 union all
select 3,    '3-Jan-2010',  0,  0,  2010 union all
select 4,    '4-Jan-2010',  1,  0,  2010 union all
select 5,    '5-Jan-2010',  1,  0,  2010 union all
select 6,    '6-Jan-2010',  1,  0,  2010 union all
select 7,    '7-Jan-2010',  1,  0,  2010 union all
select 8,    '8-Jan-2010',  1,  0,  2010 union all
select 9,    '9-Jan-2010',  0,  0,  2010 union all
select 10,  '10-Jan-2010',  0,  0,  2010 union all
select 11,  '11-Jan-2010',  1,  0,  2010 union all
select 12,  '12-Jan-2010',  1,  0,  2010 union all
select 13,  '13-Jan-2010',  1,  0,  2010 union all
select 14,  '14-Jan-2010',  1,  0,  2010 union all
select 15,  '15-Jan-2010',  1,  0,  2010 union all
select 16,  '16-Jan-2010',  0,  0,  2010 union all
select 17,  '17-Jan-2010',  0,  0,  2010 union all
select 18,  '18-Jan-2010',  1,  1,  2010 union all
select 19,  '19-Jan-2010',  1,  0,  2010 union all
select 20,  '20-Jan-2010',  1,  0,  2010 union all
select 21,  '21-Jan-2010',  1,  0,  2010 union all
select 22,  '22-Jan-2010',  1,  0,  2010 union all
select 23,  '23-Jan-2010',  0,  0,  2010 union all
select 24,  '24-Jan-2010',  0,  0,  2010 union all
select 25,  '25-Jan-2010',  1,  0,  2010 union all
select 26,  '26-Jan-2010',  1,  0,  2010;

declare @date table(
    dateID int identity(1,1) not null
,   date2 date null
,   date3 date null
,   date4 date null
,   date5 date null
);

insert into @date (date2, date3, date4, date5)
select '6/20/2009', NULL,   NULL,   '7/19/2009'   union all
select '1/2/2010',  NULL,   NULL,   '1/19/2010'   union all
select '1/4/2010',  NULL,   NULL,   '1/15/2010'  union all
select '1/2/2010',  NULL,   NULL,   '1/22/2010'  union all
select '9/17/2009', NULL,   NULL,   '10/26/2009'  union all
select '6/4/2009',  NULL,   NULL,   '6/24/2009';

;with cte as (
        select dateid
             , b.date_
          from @date
         cross apply ( 
                        Select Top (DateDiff(DAY,date2,IsNull(date5,date2))+1) DateAdd(DAY, -1+Row_Number() Over (Order By 1/0),date2) date_
                          from master..spt_values n1
                        ) b
            )

select distinct b.dateID
     , c.date2
     , c.date5
     , count(*) over(order by b.dateid) cnt
  from @cal a
  join cte b
    on a.date_ = b.date_
  join @date c
    on b.dateid = c.dateid
 where isWeekday = 1
   and isHoliday = 0

你可以换掉from master..spt_values n1

对于这样的事情:

 ;with E00(n) as (select 1 union all select 1)
     , E02(n) as (select 1 from E00 a, E00 b)
     , E04(n) as (select 1 from E02 a, E02 b)
     , E08(n) as (select 1 from E04 a, E04 b)
     , E16(n) as (select 1 from E08 a, E08 b)
     , E32(n) as (select 1 from E16 a, E16 b)
, cteTally(d) as (select row_number() over (order by n) from E32)

        , cte as (
       select dateid
            , b.date_
         from @date
  cross apply   ( 
                        select top (datediff(day,date2,isnull(date5,date2))+1) dateadd(day, -1+row_number() over(order by 1/0),date2) date_
                          from cteTally
                        ) b
                )

       select distinct b.dateID
            , c.date2
            , c.date5
            , count(*) over(order by b.dateid) cnt
         from @cal a
         join cte b
           on a.date_ = b.date_
         join @date c
           on b.dateid = c.dateid
        where isWeekday = 1
          and isHoliday = 0

【讨论】:

  • 我正在尝试计算日历 C 和从 B 系统中提取的某些日期之间的日期,结果应该是我在尝试实现文件时所说的数字。我使用的代码在 sampleCode 链接中。
  • 好的,你想计算两个日期之间的天数吗?我是否看到您只想从另一个帖子中计算他们是工作日的天数?
  • 没错,这就是我使用 sum 的原因。
  • 根据结果,我的代码运行良好,但执行时间很长,这就是为什么我正在寻找解决该问题的解决方案。
  • 我已经编辑了示例代码,这不是完整的解决方案,但您应该能够从那里弄清楚,我专注于 date2 和 date5 之间的区别。您的日历数据也需要更新,您的日期是 2009 年,而您提供的示例从 2010 年开始
猜你喜欢
  • 2019-08-30
  • 1970-01-01
  • 1970-01-01
  • 2016-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-22
  • 1970-01-01
相关资源
最近更新 更多