我在访问数据库中有几张表:
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都相同。
非常感谢任何帮助。
感谢。
修改 好的 - 下面的答案不太奏效,但它确实让我走上正轨,我能够使用以下查询:
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
答案 0 :(得分:0)
这样的事情应该有效:
[已删除原创]
试试这个(未经测试):
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连接,看看是否有效。 RDBMS我使用了最多默认值为outer,但也许你的(Access)默认为inner。
所以我认为以下内容可行(添加“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;
答案 1 :(得分:0)
我认为这样可行:
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