首先,为模糊的主题道歉,我不知道如何措辞。
在 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
对于 People 表中的每条记录,我想显示它们在数据范围内的位置,即使表 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