2017-12-14 6 views
1

私はSQLでひどいです。私はトレーナーのスケジュールでAccess内のテーブルを持っています。テーブル内の各レコードは、スケジュールは、以下の関連フィールドが含まれています。 course_codetraining_dateのstart_timeEND_TIMEトレーナー部屋SQLを使用して、日付範囲内の各日の未使用の情報をすべて返します

私はテーブルもあり、ルームroom_id,room_name,room-capacity。私の最終的な目標は、スケジュールに含まれていない日付ごとに各部屋を識別するクエリを返すことです。例えば

ルームFは、その後、私は示すために、私の最後の表を参照したいと思い、12/1812/20、および12/21で使用するために予定されている場合:

12/19 | Room F | 8 capacity 
12/22 | Room F | 8 capacity 

日付範囲12/18-12/22のクエリを実行すると、

私は近いんだけど、私が言ったように、私のSQLはとても暑いではありません。この場合は

SELECT Room.room_name, Room.room_capacity, Schedule.training_date 
FROM Room LEFT JOIN Schedule ON Room.[room_id] = Schedule.[room] 
and (Schedule.training_date) Between [Enter Start Date] And [Enter Ending Date] 
WHERE ((Schedule.room) Is Null); 

は、それは私がちょうど、個々の日付を含める必要が

| Room F | 8 capacity 

得られます。毎日と仮定

+1

あなたがこのデータベースにカレンダーのテーブルを持っていますか? –

+0

あなたは部屋のオープンスケジュールを見つけようとしていますが、正しいですか? 'LEFT JOIN'を' RIGHT JOIN'に変更するか、プライマリテーブルを 'schedule'に切り替えてください。 – Shawn

+0

私はカレンダーテーブルを持っていません。あなたが助けてくれると感じたら、私はそれを作ることができます。私は、日付ごとに1つのレコードを持つ単なるフィールドであると仮定します。休日のフィールドも含めることができます。 私は実際に部屋のオープンスケジュールを見つけようとしています、ショーン。 –

答えて

0

は、あなたが「カレンダー」テーブルとしてそれを使用することができ、少なくとも一回のスケジュールである:

select r.*, s.dte 
from (select distinct training_date as dte from schedule) as s, 
    room as r 
where not exists (select 1 
        from schedule as s2 
        where s2.training_date = s.dte and s2.room = r.room_id 
       ); 
+0

各日が 'Schedule'テーブルにあった場合、' WHERE Schedule.room IS NULL'を持つ元のクエリは動作します。 – Shawn

+0

@Shawn 。 。いいえ、そうではありません。 –

+0

@ GordonLinoff申し訳ありませんが、私はカレンダーテーブルがそれに結合された場合を意味します。 – Shawn

0

これは、あなたが出て欲しいものを得るために日付寸法/カレンダーテーブルを使用する方法を示していますのT - SQLの。 SQLのAcces実装はより多くのプリミティブですが、以下はまだ動作するように変更する必要があります。

注:これはまた、カレンダーテーブルを使用して、週末と休日を考慮します。

現在のスケジュール:

  • ルームF = 12/18,12/20,12/21
  • ルームG = 12/05,12/10
  • ルームH = 12/18,12/20
  • ルームX =いいえスケジュール

SQL Fiddle

MS SQL Serverの2014スキーマのセットアップ

CREATE TABLE schedule (id int, training_date date, room int) ; 
INSERT INTO schedule (id, training_date, room) 
VALUES 
     (1, '20171218', 1) 
    , (2, '20171220', 1) 
    , (3, '20171221', 1) 
    , (4, '20171205', 3) 
    , (5, '20171210', 3) 
    , (6, '20171218', 4) 
    , (7, '20171220', 4) 
; 

CREATE TABLE room (room_id int, room_name varchar(20), room_capacity int) ; 
INSERT INTO room (room_id, room_name, room_capacity) 
VALUES 
     (1, 'Room F', 8) 
    , (2, 'Room X', 42) 
    , (3, 'Room G', 10) 
    , (4, 'Room H', 15) 
; 

/* ******** MAKE SIMPLE CALENDAR TABLE ******** */ 

CREATE TABLE dateDim (
     theDate    DATE  NOT NULL 
    , IsWeekend   BIT   DEFAULT 0 
    , IsHoliday   BIT   DEFAULT 0 
    , IsWorkDay   BIT   DEFAULT 0 
); 

/* Populate basic details of dates. */ 
INSERT dateDim(theDate, IsWeekend, IsHoliday) 
SELECT d 
    , CONVERT(BIT, CASE WHEN DATEPART(dw,d) IN (1,7) THEN 1 ELSE 0 END) 
    , CONVERT(BIT, CASE WHEN d = '20171225' THEN 1 ELSE 0 END) /* Christmas. Calc others. */ 
FROM (
    SELECT d = DATEADD(DAY, rn - 1, '20171201') 
    FROM 
    (
     SELECT TOP (DATEDIFF(DAY, '20171201', '20171231')) 
      rn = ROW_NUMBER() OVER (ORDER BY s1.[object_id]) 
     FROM sys.all_objects AS s1 
     CROSS JOIN sys.all_objects AS s2 
     ORDER BY s1.[object_id] 
    ) AS x 
) AS y ; 

/* If not a weekend or holiday, it's a WorkDay. */ 
UPDATE dateDim 
SET IsWorkDay = CASE WHEN IsWeekend = 0 AND IsHoliday = 0 THEN 1 ELSE 0 END 
; 

MS T-SQLクエリ

SELECT Room.room_name, Room.room_capacity, dateDim.theDate 
FROM Room 
CROSS APPLY dateDim /* CROSS APPLY doesn't work in Access */ 
LEFT JOIN Schedule ON Room.room_id = Schedule.room 
    AND dateDim.theDate = Schedule.training_date 
WHERE Schedule.room Is Null 
    AND dateDim.isWeekend = 0 
    AND dateDim.isHoliday = 0 
ORDER BY dateDim.theDate, room.room_name 

Accessクエリ:私はこの1つはアクセスに働くと考えています。

SELECT Room.room_name, Room.room_capacity, c1.theDate 
FROM Room 
INNER JOIN ( 
    SELECT theDate 
    FROM dateDim 
    WHERE isWeekend = 0 
    AND isHoliday = 0 
    AND theDate BETWEEN '12/15/2017' AND '12/22/2017' -- To filter by your start/end dates 
) c1 ON 1=1 
LEFT JOIN Schedule ON Room.room_id = Schedule.room 
    AND c1.theDate = Schedule.training_date 
WHERE Schedule.room Is Null 
ORDER BY c1.theDate, room.room_name  

Results

| room_name | room_capacity | theDate | 
|-----------|---------------|------------| 
| Room F |    8 | 2017-12-01 | 
| Room G |   10 | 2017-12-01 | 
| Room H |   15 | 2017-12-01 | 
| Room X |   42 | 2017-12-01 | 
| Room F |    8 | 2017-12-04 | 
| Room G |   10 | 2017-12-04 | 
| Room H |   15 | 2017-12-04 | 
| Room X |   42 | 2017-12-04 | 
| Room F |    8 | 2017-12-05 | 
| Room H |   15 | 2017-12-05 | 
| Room X |   42 | 2017-12-05 | 
| Room F |    8 | 2017-12-06 | 
| Room G |   10 | 2017-12-06 | 
| Room H |   15 | 2017-12-06 | 
| Room X |   42 | 2017-12-06 | 
| Room F |    8 | 2017-12-07 | 
| Room G |   10 | 2017-12-07 | 
| Room H |   15 | 2017-12-07 | 
| Room X |   42 | 2017-12-07 | 
| Room F |    8 | 2017-12-08 | 
| Room G |   10 | 2017-12-08 | 
| Room H |   15 | 2017-12-08 | 
| Room X |   42 | 2017-12-08 | 
| Room F |    8 | 2017-12-11 | 
| Room G |   10 | 2017-12-11 | 
| Room H |   15 | 2017-12-11 | 
| Room X |   42 | 2017-12-11 | 
| Room F |    8 | 2017-12-12 | 
| Room G |   10 | 2017-12-12 | 
| Room H |   15 | 2017-12-12 | 
| Room X |   42 | 2017-12-12 | 
| Room F |    8 | 2017-12-13 | 
| Room G |   10 | 2017-12-13 | 
| Room H |   15 | 2017-12-13 | 
| Room X |   42 | 2017-12-13 | 
| Room F |    8 | 2017-12-14 | 
| Room G |   10 | 2017-12-14 | 
| Room H |   15 | 2017-12-14 | 
| Room X |   42 | 2017-12-14 | 
| Room F |    8 | 2017-12-15 | 
| Room G |   10 | 2017-12-15 | 
| Room H |   15 | 2017-12-15 | 
| Room X |   42 | 2017-12-15 | 
| Room G |   10 | 2017-12-18 | 
| Room X |   42 | 2017-12-18 | 
| Room F |    8 | 2017-12-19 | 
| Room G |   10 | 2017-12-19 | 
| Room H |   15 | 2017-12-19 | 
| Room X |   42 | 2017-12-19 | 
| Room G |   10 | 2017-12-20 | 
| Room X |   42 | 2017-12-20 | 
| Room G |   10 | 2017-12-21 | 
| Room H |   15 | 2017-12-21 | 
| Room X |   42 | 2017-12-21 | 
| Room F |    8 | 2017-12-22 | 
| Room G |   10 | 2017-12-22 | 
| Room H |   15 | 2017-12-22 | 
| Room X |   42 | 2017-12-22 | 
| Room F |    8 | 2017-12-26 | 
| Room G |   10 | 2017-12-26 | 
| Room H |   15 | 2017-12-26 | 
| Room X |   42 | 2017-12-26 | 
| Room F |    8 | 2017-12-27 | 
| Room G |   10 | 2017-12-27 | 
| Room H |   15 | 2017-12-27 | 
| Room X |   42 | 2017-12-27 | 
| Room F |    8 | 2017-12-28 | 
| Room G |   10 | 2017-12-28 | 
| Room H |   15 | 2017-12-28 | 
| Room X |   42 | 2017-12-28 | 
| Room F |    8 | 2017-12-29 | 
| Room G |   10 | 2017-12-29 | 
| Room H |   15 | 2017-12-29 | 
| Room X |   42 | 2017-12-29 | 

Access-method Results

| room_name | room_capacity | theDate | 
|-----------|---------------|------------| 
| Room F |    8 | 2017-12-15 | 
| Room G |   10 | 2017-12-15 | 
| Room H |   15 | 2017-12-15 | 
| Room X |   42 | 2017-12-15 | 
| Room G |   10 | 2017-12-18 | 
| Room X |   42 | 2017-12-18 | 
| Room F |    8 | 2017-12-19 | 
| Room G |   10 | 2017-12-19 | 
| Room H |   15 | 2017-12-19 | 
| Room X |   42 | 2017-12-19 | 
| Room G |   10 | 2017-12-20 | 
| Room X |   42 | 2017-12-20 | 
| Room G |   10 | 2017-12-21 | 
| Room H |   15 | 2017-12-21 | 
| Room X |   42 | 2017-12-21 | 
| Room F |    8 | 2017-12-22 | 
| Room G |   10 | 2017-12-22 | 
| Room H |   15 | 2017-12-22 | 
| Room X |   42 | 2017-12-22 | 
+0

また、カレンダーテーブルは、データベースからのテーブルまたはクエリに適用される可能性のある日付をカバーする必要があります。すなわち、私は通常、1950年1月1日から2031年12月31日まで、または100年にわたるカレンダーテーブルを作成します。より広い範囲が必要な場合は、調整するのがかなり簡単です。 – Shawn

関連する問題