Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 有日期的表,有周数的表,是否合并?_Sql_Sql Server 2005 - Fatal编程技术网

Sql 有日期的表,有周数的表,是否合并?

Sql 有日期的表,有周数的表,是否合并?,sql,sql-server-2005,Sql,Sql Server 2005,我有两张桌子。表1: StuAp_Id StuAp_StaffID StuAp_Date StuAp_Attended 16 77000002659366 2011-09-07 Yes 17 77000002659366 2011-09-14 Yes 18 77000002659366 2011-09-14 Yes 19 77000002659366 2011-09-14 No 20

我有两张桌子。表1:

StuAp_Id    StuAp_StaffID   StuAp_Date  StuAp_Attended
16          77000002659366  2011-09-07  Yes
17          77000002659366  2011-09-14  Yes
18          77000002659366  2011-09-14  Yes
19          77000002659366  2011-09-14  No
20          77000001171783  2011-09-19  Yes
表2:

Year    Week    Start
2011    1   2011-09-05 00:00:00.000
2011    2   2011-09-12 00:00:00.000
2011    3   2011-09-19 00:00:00.000
2011    4   2011-09-26 00:00:00.000
2011    5   2011-10-03 00:00:00.000
2011    6   2011-10-10 00:00:00.000
2011    7   2011-10-17 00:00:00.000
2011    8   2011-10-24 00:00:00.000
2011    9   2011-10-31 00:00:00.000
我将如何连接这两个表以生成如下内容:

StuAp_Id    StuAp_StaffID   StuAp_Date  StuAp_Attended  Week
16          77000002659366  2011-09-07  Yes             1
17          77000002659366  2011-09-14  Yes             2
18          77000002659366  2011-09-14  Yes             2
19          77000002659366  2011-09-14  No              2
20          77000001171783  2011-09-19  Yes             3

提前感谢

我不知道sql2k5的详细信息,也没有测试,但我会使用一个子选择,例如

select table_1.*, 
       [week] = (select isnull(max([week]), 0) 
                   from table_2 
                  where table_1.StuAp_Date >= table_2.start)
  from table_1

我不知道sql2k5的细节,也没有一个可以测试,但我会使用一个子选择

select table_1.*, 
       [week] = (select isnull(max([week]), 0) 
                   from table_2 
                  where table_1.StuAp_Date >= table_2.start)
  from table_1
可以使用GROUPBY子句编写简单的内部联接

可以使用GROUPBY子句编写简单的内部联接

救命啊

create table StuAp (
    StuAp_Id        int,
    StuAp_StaffID   bigint,
    StuAp_Date      datetime,
    StuAp_Attended  varchar(3)
)

create table Weeks (
    Year    int,
    Week    int,
    Start   datetime
)

insert into StuAp
values (16, 77000002659366, {d '2011-09-07'}, 'Yes'),
    (17, 77000002659366, {d '2011-09-14'}, 'Yes'),
    (18, 77000002659366, {d '2011-09-14'}, 'Yes'),
    (19, 77000002659366, {d '2011-09-14'}, 'No'),
    (20, 77000001171783, {d '2011-09-19'}, 'Yes')

insert into Weeks
values (2011, 1, {d '2011-09-05'}),
(2011, 2, {d '2011-09-12'}),
(2011, 3, {d '2011-09-19'}),
(2011, 4, {d '2011-09-26'}),
(2011, 5, {d '2011-10-03'}),
(2011, 6, {d '2011-10-10'}),
(2011, 7, {d '2011-10-17'}),
(2011, 8, {d '2011-10-24'}),
(2011, 9, {d '2011-10-31'})



;with OrderedWeeks as (
    select ROW_NUMBER() OVER (ORDER BY year, week) as row, w.*
    from Weeks w
), Ranges as (
    select w1.*, w2.Start as Finish
    from OrderedWeeks w1 inner join
        OrderedWeeks w2 on w1.row = w2.row - 1
)
select s.StuAp_Id, s.StuAp_StaffID, s.StuAp_Date, s.StuAp_Attended, r.Week
from StuAp s inner join
    Ranges r on s.StuAp_Date >= r.Start and s.StuAp_Date < r.Finish
这应该也能很好地扩展

诚然,如果你发现自己经常这样做,你真的应该考虑改变周表的结构,包括完成日期。您甚至可以将其设置为索引视图,或者假设数据很少更改,您可以保留原始表,并使用触发器或SQL代理作业来保持包含Finish的副本的最新状态。

create table StuAp (
    StuAp_Id        int,
    StuAp_StaffID   bigint,
    StuAp_Date      datetime,
    StuAp_Attended  varchar(3)
)

create table Weeks (
    Year    int,
    Week    int,
    Start   datetime
)

insert into StuAp
values (16, 77000002659366, {d '2011-09-07'}, 'Yes'),
    (17, 77000002659366, {d '2011-09-14'}, 'Yes'),
    (18, 77000002659366, {d '2011-09-14'}, 'Yes'),
    (19, 77000002659366, {d '2011-09-14'}, 'No'),
    (20, 77000001171783, {d '2011-09-19'}, 'Yes')

insert into Weeks
values (2011, 1, {d '2011-09-05'}),
(2011, 2, {d '2011-09-12'}),
(2011, 3, {d '2011-09-19'}),
(2011, 4, {d '2011-09-26'}),
(2011, 5, {d '2011-10-03'}),
(2011, 6, {d '2011-10-10'}),
(2011, 7, {d '2011-10-17'}),
(2011, 8, {d '2011-10-24'}),
(2011, 9, {d '2011-10-31'})



;with OrderedWeeks as (
    select ROW_NUMBER() OVER (ORDER BY year, week) as row, w.*
    from Weeks w
), Ranges as (
    select w1.*, w2.Start as Finish
    from OrderedWeeks w1 inner join
        OrderedWeeks w2 on w1.row = w2.row - 1
)
select s.StuAp_Id, s.StuAp_StaffID, s.StuAp_Date, s.StuAp_Attended, r.Week
from StuAp s inner join
    Ranges r on s.StuAp_Date >= r.Start and s.StuAp_Date < r.Finish
SET ANSI_WARNINGS ON;
GO

DECLARE @Table1 TABLE
(
     StuAp_Id       INT PRIMARY KEY
    ,StuAp_StaffID  NUMERIC(14,0) NOT NULL
    ,StuAp_Date     DATETIME NOT NULL
    ,StuAp_Attended VARCHAR(3) NOT NULL
    ,StuAp_DateOnly AS DATEADD(DAY, DATEDIFF(DAY,0,StuAp_Date), 0) PERSISTED
);

INSERT  @Table1 
SELECT  16,77000002659366  ,'2011-09-07','Yes'
UNION ALL
SELECT  17,77000002659366  ,'2011-09-14','Yes'
UNION ALL
SELECT  18,77000002659366  ,'2011-09-14','Yes'
UNION ALL
SELECT  19,77000002659366  ,'2011-09-14','No'
UNION ALL
SELECT  20,77000001171783  ,'2011-09-19','Yes';

DECLARE @Table2 TABLE
(
     Year   INT NOT NULL
    ,Week    INT NOT NULL
    ,Start  DATETIME NOT NULL
    ,[End] AS DATEADD(DAY,6,Start) PERSISTED
    ,PRIMARY KEY(Year, Week)
    ,UNIQUE(Start)
);

INSERT  @Table2
SELECT  2011,1   ,'2011-09-05 00:00:00.000'
UNION ALL
SELECT  2011,2   ,'2011-09-12 00:00:00.000'
UNION ALL
SELECT  2011,3   ,'2011-09-19 00:00:00.000'
UNION ALL
SELECT  2011,4   ,'2011-09-26 00:00:00.000'
UNION ALL
SELECT  2011,5   ,'2011-10-03 00:00:00.000'
UNION ALL
SELECT  2011,6   ,'2011-10-10 00:00:00.000'
UNION ALL
SELECT  2011,7   ,'2011-10-17 00:00:00.000'
UNION ALL
SELECT  2011,8   ,'2011-10-24 00:00:00.000'
UNION ALL
SELECT  2011,9   ,'2011-10-31 00:00:00.000';

--Solution 1 : if StuAp_Date has only date part
SELECT  a.*, b.Week
FROM    @Table1 a
INNER JOIN @Table2 b ON a.StuAp_Date BETWEEN b.Start AND b.[End]

--Solution 2 : if StuAp_Date has only date part
SELECT  a.*, b.Week
FROM    @Table1 a
INNER JOIN @Table2 b ON a.StuAp_Date BETWEEN b.Start AND DATEADD(DAY,6,b.Start)

--Solution 3 : if StuAp_Date has date & time 
SELECT  a.*, b.Week
FROM    @Table1 a
INNER JOIN @Table2 b ON a.StuAp_DateOnly BETWEEN b.Start AND b.[End]

--Solution 4 : if StuAp_Date has date & time 
SELECT  a.*, b.Week
FROM    @Table1 a
INNER JOIN @Table2 b ON DATEADD(DAY, DATEDIFF(DAY,0,a.StuAp_Date), 0) BETWEEN b.Start AND DATEADD(DAY,6,b.Start)
这应该也能很好地扩展


诚然,如果你发现自己经常这样做,你真的应该考虑改变周表的结构,包括完成日期。您甚至可以将其设置为索引视图,或者假设数据很少更改,您可以保留原始表,并使用触发器或SQL代理作业来保持包含Finish的副本最新。

请注意!当心危险!这个答案基本上是正确的,但需要调整以确保所有日期不等于第52周。因此,内部连接现在显示:内部连接表2 ON STUAP_DATE>=开始和STUAP_DATE这个答案基本上是正确的,但需要调整以确保所有日期不等于第52周。因此,内部联接现在显示为:内部联接表2 ON STUAP_DATE>=开始和STUAP_DATE
SET ANSI_WARNINGS ON;
GO

DECLARE @Table1 TABLE
(
     StuAp_Id       INT PRIMARY KEY
    ,StuAp_StaffID  NUMERIC(14,0) NOT NULL
    ,StuAp_Date     DATETIME NOT NULL
    ,StuAp_Attended VARCHAR(3) NOT NULL
    ,StuAp_DateOnly AS DATEADD(DAY, DATEDIFF(DAY,0,StuAp_Date), 0) PERSISTED
);

INSERT  @Table1 
SELECT  16,77000002659366  ,'2011-09-07','Yes'
UNION ALL
SELECT  17,77000002659366  ,'2011-09-14','Yes'
UNION ALL
SELECT  18,77000002659366  ,'2011-09-14','Yes'
UNION ALL
SELECT  19,77000002659366  ,'2011-09-14','No'
UNION ALL
SELECT  20,77000001171783  ,'2011-09-19','Yes';

DECLARE @Table2 TABLE
(
     Year   INT NOT NULL
    ,Week    INT NOT NULL
    ,Start  DATETIME NOT NULL
    ,[End] AS DATEADD(DAY,6,Start) PERSISTED
    ,PRIMARY KEY(Year, Week)
    ,UNIQUE(Start)
);

INSERT  @Table2
SELECT  2011,1   ,'2011-09-05 00:00:00.000'
UNION ALL
SELECT  2011,2   ,'2011-09-12 00:00:00.000'
UNION ALL
SELECT  2011,3   ,'2011-09-19 00:00:00.000'
UNION ALL
SELECT  2011,4   ,'2011-09-26 00:00:00.000'
UNION ALL
SELECT  2011,5   ,'2011-10-03 00:00:00.000'
UNION ALL
SELECT  2011,6   ,'2011-10-10 00:00:00.000'
UNION ALL
SELECT  2011,7   ,'2011-10-17 00:00:00.000'
UNION ALL
SELECT  2011,8   ,'2011-10-24 00:00:00.000'
UNION ALL
SELECT  2011,9   ,'2011-10-31 00:00:00.000';

--Solution 1 : if StuAp_Date has only date part
SELECT  a.*, b.Week
FROM    @Table1 a
INNER JOIN @Table2 b ON a.StuAp_Date BETWEEN b.Start AND b.[End]

--Solution 2 : if StuAp_Date has only date part
SELECT  a.*, b.Week
FROM    @Table1 a
INNER JOIN @Table2 b ON a.StuAp_Date BETWEEN b.Start AND DATEADD(DAY,6,b.Start)

--Solution 3 : if StuAp_Date has date & time 
SELECT  a.*, b.Week
FROM    @Table1 a
INNER JOIN @Table2 b ON a.StuAp_DateOnly BETWEEN b.Start AND b.[End]

--Solution 4 : if StuAp_Date has date & time 
SELECT  a.*, b.Week
FROM    @Table1 a
INNER JOIN @Table2 b ON DATEADD(DAY, DATEDIFF(DAY,0,a.StuAp_Date), 0) BETWEEN b.Start AND DATEADD(DAY,6,b.Start)