1

まず第一に、漠然とした主題についてお詫び申し上げます。これをどのように表現すればよいかわかりません。

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
4

1 に答える 1