表与日期,表与周数,加在一起?

时间:2011-10-11 08:05:40

标签: 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          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

提前致谢

4 个答案:

答案 0 :(得分:2)

不知道sql2k5的具体细节(没有一个可以测试),但我会使用子选择,例如。

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

答案 1 :(得分:2)

您可以使用INNER JOIN子句编写简单的GROUP BY

SELECT  Table1.*
        ,MAX(WEEK) AS WEEK 
            FROM Table1
                    INNER JOIN Table2 ON STUAP_DATE >= START 
            GROUP BY STUAP_ID,STUAP_STAFFID,STUAP_DATE,STUAP_ATTENDED

答案 2 :(得分:1)

CTEs救援!

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

这也应该很好地扩展。

老实说,如果您经常发现这样的查询,您应该考虑更改Weeks表的结构以包含完成日期。您甚至可以将其设为索引视图,或者(假设数据很少更改),您可以保留原始表并使用触发器或SQL代理作业来保留包含完成最新版本的副本。

答案 3 :(得分:0)

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)