选择在两个字段上加入查询?

时间:2010-04-30 17:28:55

标签: sql ms-access select join

我在访问数据库中有几张表:

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

2 个答案:

答案 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