2010-04-30 101 views
1

我有一个访问数据库中的几个表:选择查询加入两个字段?

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

你不应该GROUP BY t1.LocationID因为你没有选择它,它始终是2。我也要推荐使用比“t1”更好的名字来表示可读性。另一个问题是一个谜题...... t1和t2之间是否存在1对1的关系?另外,尝试删除join和subselect以查看是否全部获取您需要的日期(我会在下面添加到我的答案中) – 2010-04-30 20:04:29

回答

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 JOIN,那么它会删除从t1行没有在T2匹配的行。尝试明确设置一个左外部连接,看看是否有效。关系型数据库管理系统我使用最多的默认设置为外层,但也许你的(访问)默认为内层。

所以我想下面的工作将添加“外部”和删除“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; 
+0

一些注释: 1.我必须切换查询或Acccess中的'group by'和'where'部分甚至不会让我保存它。 2.在试图运行它,我得到一个错误: 试图执行一个查询,不包括指定表达式“numproductsdelivered”作为一个聚合功能的一部分。 – wtollett 2010-04-30 18:00:29

+0

是的,你不能选择任何你没有分组(除了agreggated值)...在这种情况下,我认为你可以简单地由t3.date,t2.numproductsdelivered更改为组,因为这个额外的分组赢得了' t改变结果(你只有一个numproducts在每个日期交付)。我修复了我的答案(也许并非完全) – 2010-04-30 18:03:22

+0

这仍然不起作用,但它帮助我找到了一个似乎正在工作的答案,除了一种情况(参见上文)。 – wtollett 2010-04-30 19:44:56

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 [email protected] 
GROUP BY L2.LocationId, L2.Date 
+0

突出的是“案例”...为什么我没有想到这一点? :)不知道其余的工作... – 2010-04-30 20:14:35

+0

这是一个有关Access/Jet/ACE数据库的问题的T-SQL答案(我在问题本身或标签中看不到SQL Server)。 -1不注意并提供非工作答案。 – 2010-04-30 21:12:17

+0

是的,你是对的。我没有看到它是关于Access,我的错误。使用Access而不是CASE,您应该使用IIF来获得相同的结果。 – Claudia 2010-05-03 12:54:27