まず第一に、漠然とした主題についてお詫び申し上げます。これをどのように表現すればよいかわかりません。
SQLでは、テーブルA =人、テーブルB =特定の日付の場所という2つのテーブルがあります。
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 に場所が設定されていなくても、People テーブルの各レコードについて、データ範囲の場所を表示したいと考えています。
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