2013-07-23 65 views
1

首先,對於模糊主題的道歉,我不知道該怎麼說。SQL:顯示給定日期範圍內的人員記錄選擇信息

在SQL中,我有兩個表,表A =人,表B =他們在特定日期的位置。

Table A 
PK Name 
1 Fred 
2 John 
3 James 

Table B 
PK Date  PersFK Location 
1 2013-01-01 1  Office 
2 2013-01-01 2  Meeting 
3 2013-01-02 1  Office 
4 2013-01-03 1  Meeting 
5 2013-01-04 3  Mars 
6 2013-01-04 2  Moon 

對於每一個在人民表中的記錄,我想展示自己的位置的數據範圍,即使沒有位置已經表B中設置

Date  Name  Location 
2013-01-01 Fred  Office 
2013-01-01 John  Meeting 
2013-01-01 James  NULL 
2013-01-02 Fred  Office 
2013-01-02 John  NULL 
2013-01-02 James  NULL 
2013-01-03 Fred  Office 
2013-01-03 John  NULL 
2013-01-03 James  NULL 
2013-01-04 Fred  NULL 
2013-01-04 John  Moon 
2013-01-04 James  Mars 
2013-01-05 Fred  NULL 
2013-01-05 John  NULL 
2013-01-05 James  NULL 

這是我到目前爲止已經提出,但是當人沒有在表b中設置位置時它不顯示記錄。也許我過於複雜,或者無法讓我的頭腦解決問題。任何幫助將不勝感激

DECLARE @YEAR INT = 2013 
DECLARE @Month INT = 7 

--Movements 
DECLARE @tblMovements TABLE (PersPK INT, PersName VARCHAR(MAX), PersDept VARCHAR(MAX), PersOffice VARCHAR(MAX), PersCompany VARCHAR(MAX), MovDate DATE, MovLocation VARCHAR(MAX)) 

--Dates 
DECLARE @StartDate DATETIME = DateAdd(yy, @Year-1900, DateAdd(m, @Month - 1, 0)) 
DECLARE @EndDate DATETIME 
DECLARE @tblDates TABLE (DateIN DATETIME) 

SELECT @StartDate = DATEADD(s,0,DATEADD(mm, DATEDIFF(m,0,@StartDate),0)) --FirstDayOfMonth 
SELECT @EndDate = DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@StartDate)+1,0)) --LastDayOfMonth 

;WITH Dates AS (
SELECT @StartDate AS myDate 
UNION ALL 
SELECT DATEADD(DAY,1,myDate) 
FROM Dates 
WHERE DATEADD(DAY,1,myDate) <= @EndDate 
) 

INSERT INTO @tblDates (DateIN) 
SELECT myDate 
FROM Dates 
OPTION (MAXRECURSION 0) 

INSERT INTO @tblMovements (PersPK, PersName, PersDept, PersOffice, PersCompany, MovDate, MovLocation) 
SELECT 
    P.Pers_PK 
    ,P.Pers_FName + ' ' + P.Pers_SName + ' (' + P.Pers_Ext + ')' [Name] 
    ,P.DeptShortName 
    ,P.ShortName 
    ,P.CompanySName 
    ,CONVERT(DATE, M.[Mov_Date], 103) [Mov Date] 
    ,M.[Mov_Location] 
FROM [Pers_People_T] P 
LEFT JOIN Pers_Movements_T M ON M.Pers_FK = P.Pers_PK AND M.Mov_Date Between @StartDate AND DateAdd(dd,0,@EndDate) 
WHERE P.Pers_Department_FK = 6 
AND P.Active = 1 

SELECT * FROM @tblDates D 
FULL JOIN @tblMovements M ON D.DateIN = M.MovDate 

編輯:感謝t-clausen.dk,這就是我想出到底

declare @year int = 2013 
declare @month int = 7 

declare @tableA table(PK int, name varchar(5)) 
declare @tableB table(PK int, Date date, PersFK int, Location varchar(10)) 

--Dates 
DECLARE @StartDate DATETIME = DateAdd(yy, @Year-1900, DateAdd(m, @Month - 1, 0)) 
DECLARE @EndDate DATETIME 
SELECT @StartDate = DATEADD(s,0,DATEADD(mm, DATEDIFF(m,0,@StartDate),0)) --FirstDayOfMonth 
SELECT @EndDate = DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@StartDate)+1,0)) --LastDayOfMonth 
DECLARE @tblDates TABLE (DateIN DATETIME) 

;WITH Dates AS (
SELECT @StartDate AS myDate 
UNION ALL 
SELECT DATEADD(DAY,1,myDate) 
FROM Dates 
WHERE DATEADD(DAY,1,myDate) <= @EndDate 
) 

INSERT INTO @tblDates (DateIN) 
SELECT myDate 
FROM Dates 
OPTION (MAXRECURSION 0) 


insert @tableA values (1, 'Fred'), (2, 'John'),(3, 'James') 

insert @TableB values(1, '2013-01-01', 1, 'Office'), 
(2, '2013-07-01', 2,  'Meeting'), 
(3, '2013-07-02', 1,  'Office'), 
(4, '2013-07-03', 1,  'Meeting'), 
(5, '2013-07-04', 3,  'Mars'), 
(6, '2013-07-04', 2,  'Moon') 

select coalesce(c.DateIN, b.Date) Date, a.name, b.PersFK, b.location 
from 
(
SELECT * FROM @tblDates 
) c 
cross join 
@tableA a 
left join 
@tableB b 
on 
a.PK = b.PersFk 
and c.DateIN = b.date 
order by Date, Name 

回答

1

也許這可以讓你的生活更輕鬆:

declare @year int = 2013 
declare @month int = 7 

declare @tableA table(PK int, name varchar(5)) 
declare @tableB table(PK int, Date date, PersFK int, Location varchar(10)) 

insert @tableA values (1, 'Fred'), (2, 'John'),(3, 'James') 

insert @TableB values(1, '2013-01-01', 1, 'Office'), 
(2, '2013-07-01', 2,  'Meeting'), 
(3, '2013-07-02', 1,  'Office'), 
(4, '2013-07-03', 1,  'Meeting'), 
(5, '2013-07-04', 3,  'Mars'), 
(6, '2013-07-04', 2,  'Moon') 


select coalesce(c.Date, b.Date) Date, a.name, b.PersFK, b.location 
from 
(
select dateadd(month, (@year-1900)*[email protected] - 1, number) Date 
from 
master..spt_values 
where type = 'p' 
and number < day(dateadd(month, (@year-1900)*[email protected], -1)) 
) c 
cross join 
@tableA a 
left join 
@tableB b 
on 
a.PK = b.PersFk 
and c.date = b.date 
order by Date, Name