Таблица с датами, таблица с номерами недель, объединиться? - PullRequest
0 голосов
/ 11 октября 2011

У меня есть две таблицы. Таблица 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 ]

2 голосов
/ 11 октября 2011

Вы можете написать простой 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 голосов
/ 11 октября 2011

не знаю о спецификациях на 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 голос
/ 11 октября 2011

CTE на помощь!

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, чтобы сохранить копию, содержащую «Готово», в актуальном состоянии.

0 голосов
/ 11 октября 2011
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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...