Выбрать запрос, объединенный на двух полях? - PullRequest
1 голос
/ 30 апреля 2010

У меня есть несколько таблиц в базе данных доступа:

ID | LocationName
1  | Location1
2  | Location2

ID | LocationID | Date  | NumProductsDelivered
1  |     1      | 12/10 |      3
2  |     1      | 01/11 |      2
3  |     1      | 02/11 |      2
4  |     2      | 11/10 |      1
5  |     2      | 12/10 |      1

ID | LocationID | Date  | NumEmployees | EmployeeType
1  |     1      | 12/10 |      10      |      1 (=Permanent)
2  |     1      | 12/10 |       3      |      2 (=Temporary)
3  |     1      | 12/10 |       1      |      3 (=Support)
4  |     2      | 10/10 |       1      |      1
5  |     2      | 11/10 |       2      |      1
6  |     2      | 11/10 |       1      |      2
7  |     2      | 11/10 |       1      |      3
8  |     2      | 12/10 |       2      |      1
9  |     2      | 12/10 |       1      |      3

Что я хочу сделать, это передать LocationID в качестве параметра и получить что-то похожее на следующую таблицу. Итак, если я передам 2 в качестве моего LocationID, я должен получить:

Date  | NumProductsDelivered | NumPermanentEmployees | NumSupportEmployees
10/10 |                      |           1           |           
11/10 |          1           |           2           |          1
12/10 |          1           |           2           |          1

Похоже, это должен быть довольно простой запрос. Мне действительно даже не нужна первая таблица, кроме как для заполнения поля со списком в форме, из которой пользователь выбирает место, для которого он хочет получить отчет. К сожалению, все, что я сделал, привело к тому, что я получил намного больше данных, чем я должен был получить. Моя путаница заключается в том, как настроить соединение (предположительно, это то, что я ищу здесь), учитывая, что я хочу, чтобы и date, и locationID были одинаковыми для каждой строки в наборе результатов.

Любая помощь будет высоко ценится.

Спасибо.

EDIT: Хорошо, ответ ниже не совсем сработал, но он поставил меня на правильный путь, и я смог использовать следующий запрос:

SELECT t1.Date, t2.NumProductsDelivered, 
  (SELECT t1a.NumEmployees
    FROM table3 t1a
    WHERE t1a.EmployeeType=1 AND t1a.LocationID=t1.LocationID AND t1a.Date= t1.Date)
  AS "PermEmps", 
  (SELECT t1b.NumEmployees
    FROM table3 t1b
    WHERE t1b.EmployeeType=3 AND t1b.LocationID=t1.LocationID AND t1b.Date=t1.Date)
  AS "SupportEmps"
FROM table3 AS t1 LEFT JOIN table2 AS t2 ON (t2.Date=t1.Date) 
  AND (t2.LocationID=t1.LocationID)
WHERE t1.LocationID=2
GROUP BY t1.Date, t1.LocationID, t2.NumProductsDelivered;

Это дает мне результаты, которые я искал. Тем не менее, в случае, когда у места есть разрыв между поставляемыми продуктами, я не вижу правильных результатов. Похоже, что набор записей останавливается, как только появляется пустая строка, и никогда больше не восстанавливается. Итак, где я мог бы увидеть это:

Date  | NumProductsDelivered | NumPermanentEmployees | NumSupportEmployees
10/10 |                      |           1           |           
11/10 |          1           |           2           |          1
12/10 |          1           |           2           |          1
01/10 |          2           |                       |          1
06/10 |          1           |                       |

Я вижу только это:

Date  | NumProductsDelivered | NumPermanentEmployees | NumSupportEmployees
10/10 |                      |           1           |           
11/10 |          1           |           2           |          1
12/10 |          1           |           2           |          1
01/10 |          2           |                       |          1

Ответы [ 2 ]

0 голосов
/ 01 мая 2010

Я думаю, что это будет работать:

DECLARE @LocationId int

SET @LocationId=2

SELECT L2.LocationId, L2.Date, COUNT(DISTINCT NumProductsDelivered) as NumProductsDelivered,
 SUM(case when L2.EmployeeType =1 then NumEmployees else 0 end) as NumPermanentEmployees,
 SUM(case when L2.EmployeeType =3 then NumEmployees else 0 end) as NumSupportEmployees
FROM L1 
    RIGHT JOIN L2
        ON L1.LocationID=L2.LocationID
        AND L1.Date=L2.Date
WHERE L2.LocationId=@LocationId
GROUP BY L2.LocationId, L2.Date
0 голосов
/ 30 апреля 2010

Примерно так должно работать:

[удалено оригинал]

Попробуйте вместо этого (не проверено):

select t3.date, t2.numproductsdelivered, 
  (select sum(t3.numemployees)
   from table3 t3a
   where t3a.locationid = t3.locationid and t3a.date = t3.date and t3a.employeetype = 1
  ) as numpermanentemployees,
  (select sum(t3.numemployees)
   from table3 t3b
   where t3b.locationid = t3.locationid and t3b.date = t3.date and t3b.employeetype = 3
  ) as numsupportemployees
from table3 as t3
left join table2 as t2 on t2.locationid = t3.locationid and t2.date = t3.date
where t3.locationid = 2
group by t3.date, t2.numproductsdelivered

Если вы не против иметь отдельные строки для каждого типа сотрудников, это можно упростить:

select t3.date, t2.numproductsdelivered, t3.employeetype, sum(t3.numemployees) as numemployees
from table3 as t3
left join table2 as t2 on t2.locationid = t3.locationid and t2.date = t3.date
where t3.locationid = 2 and t3.employeetype in (1, 3)
group by t3.date, t2.numproductsdelivered, t3.employeetype

Редактировать: Попробуйте этот запрос:

SELECT t1.Date
FROM table3 AS t1
WHERE t1.LocationID=2
GROUP BY t1.Date

... и посмотрите, получите ли вы все даты.

Затем добавьте левое соединение:

SELECT t1.Date, t2.NumProductsDelivered
FROM table3 AS t1 LEFT JOIN table2 AS t2 ON (t2.Date=t1.Date) 
  AND (t2.LocationID=t1.LocationID)
WHERE t1.LocationID=2
GROUP BY t1.Date, t1.LocationID, t2.NumProductsDelivered;

Если он выполняет левое соединение INNER, он удалит строки из t1, которые не имеют совпадающей строки в t2. Попробуйте явно установить левое соединение OUTER и посмотрите, работает ли это. СУБД, которые я использовал по умолчанию для внешних, но, возможно, для ваших (Access) по умолчанию - для внутренних.

Так что я думаю, что будет работать следующее (добавьте "OUTER" и удалите "t1.LocationId"):

SELECT t1.Date, t2.NumProductsDelivered, 
  (SELECT t1a.NumEmployees
    FROM table3 t1a
    WHERE t1a.EmployeeType=1 AND t1a.LocationID=t1.LocationID AND t1a.Date= t1.Date)
  AS "PermEmps", 
  (SELECT t1b.NumEmployees
    FROM table3 t1b
    WHERE t1b.EmployeeType=3 AND t1b.LocationID=t1.LocationID AND t1b.Date=t1.Date)
  AS "SupportEmps"
FROM table3 AS t1 LEFT OUTER JOIN table2 AS t2 ON (t2.Date=t1.Date) 
  AND (t2.LocationID=t1.LocationID)
WHERE t1.LocationID=2
GROUP BY t1.Date, t2.NumProductsDelivered;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...