加入返回太多信息

时间:2017-07-31 19:07:19

标签: sql

我有2张桌子

Table1
+---------+--------+-------+----+
| CALDATE | GROOMS | ROOMS | fn |
+---------+--------+-------+----+
| 1/5/18  |     15 |    17 | A12|
| 1/5/18  |      0 |     0 | A12|
| 1/6/18  |      0 |     0 | B34|
| 1/6/18  |     75 |    77 | B34|
| 1/7/18  |    123 |   125 | C56|
| 1/7/18  |      0 |     0 | C56|
+---------+--------+-------+----+

-

Table2
+----------+--------+----+
| ROOMDATE | pickup | FN |
+----------+--------+----+
| 1/5/18   |      0 | A12|
| 1/5/18   |      2 | A12|
| 1/5/18   |      1 | A12|
| 1/5/18   |      7 | A12|
| 1/6/18   |      2 | B34|
| 1/6/18   |      1 | B34|
| 1/6/18   |     13 | B34|
| 1/7/18   |      3 | C56|
| 1/7/18   |      0 | C56|
| 1/7/18   |     12 | C56|
+----------+--------+----+

查询我使用的每个

Select caldate as date, sum(grooms) as g, sum (rooms) as r
from Table1

Select roomdate as date, sum(pickup) as p
from Table2

这些都给了我期待的信息,但是当我尝试加入它们时,事情就变得很糟糕。我希望有像

这样的东西
Select caldate as date,
sum(grooms) as g,
sum(rooms) as r,
sum(pickup) as p
from Table1
inner join table2 on table1.fn = table2.fn

但是每种方式的回报都太高了。

如何加入这些查询以便获得预期的

输出
+--------+-----+-----+----+----+
|  Date  |  g  |  r  | p  | fn |
+--------+-----+-----+----+----+
| 1/5/18 |  15 |  17 | 10 | A12|
| 1/6/18 |  75 |  77 | 16 | B34|
| 1/7/18 | 123 | 125 | 15 | C56|
+--------+-----+-----+----+----+

4 个答案:

答案 0 :(得分:1)

第一个表中的每一行都将根据您的连接谓词与另一个表中的每个可用行匹配。以fn = A12为例:由于table1中有2行,table2中有4行,因此结果集中最后会有(4x2)8行。这将导致你的金额高于应有的金额。

解决此问题的一种方法是使用派生表来获取总和,然后将它们连接在一起:

SELECT t1.date, g, r, p, t1.fn
FROM (SELECT fn, caldate as date, sum(grooms) as g, sum (rooms) as r
      FROM Table1
      GROUP BY fn, caldate) t1
JOIN (SELECT fn, roomdate as date, sum(pickup) as p
      FROM Table2
      GROUP BY fn, roomdate) t2 on t1.fn = t2.fn

这可确保在连接之前从每个表返回一行。

答案 1 :(得分:0)

你应该按'caldate'进行分组。这样你只能得到每个日期的总和。

Select caldate as date,
sum(grooms) as g,
sum(rooms) as r,
sum(pickup) as p
from Table1
inner join table2 on table1.fn = table2.fn
group by caldate

答案 2 :(得分:0)

这是一个答案,允许您按FN和日期进行分组:

select format(caldate, 'M/d/yyyy') as date, sum(grooms) as g, sum(rooms) as r, t2.p, t1.fn
from Table1 t1
inner join (
    select fn, roomdate, sum(pickup) as p from Table2 group by fn, roomdate
    )t2 on t1.fn = t2.fn and t1.caldate = t2.roomdate
group by t1.caldate, t1.fn, t2.p

我使用DML语句创建了一些示例数据,因此您可以通过FN和日期的不同组合以及输出来测试分组:

declare @t1 table (caldate datetime, grooms int, rooms int, fn varchar(3))
declare @t2 table (roomdate datetime, pickup int, fn varchar(3))

insert into @t1 select '1/5/18', 15, 17,'A12'
insert into @t1 select '1/5/18',  0,  0,'A12'
insert into @t1 select '1/6/18',  0,  0,'B34'
insert into @t1 select '1/6/18', 75, 77,'B34'
insert into @t1 select '1/7/18',123,125,'C56'
insert into @t1 select '1/8/18',100,200,'C56' -- changed to 1/8/18, changed vals

insert into @t2 select '1/5/18', 0 ,'A12'
insert into @t2 select '1/5/18', 2 ,'A12'
insert into @t2 select '1/5/18', 1 ,'A12'
insert into @t2 select '1/5/18', 7 ,'A12'
insert into @t2 select '1/6/18', 2 ,'B34'
insert into @t2 select '1/6/18', 1 ,'B34'
insert into @t2 select '1/6/18',13 ,'B34'
insert into @t2 select '1/7/18', 3 ,'C56'
insert into @t2 select '1/7/18', 0 ,'C56'
insert into @t2 select '1/8/18',12 ,'C56' -- changed to 1/8/18

select format(caldate, 'M/d/yyyy') as date, sum(grooms) as g, sum(rooms) as r, t2.p, t1.fn
from @t1 t1
inner join (
    select fn, roomdate, sum(pickup) as p from @t2 group by fn, roomdate
    )t2 on t1.fn = t2.fn and t1.caldate = t2.roomdate
group by t1.caldate, t1.fn, t2.p

输出:

date        g       r       p       fn
1/5/2018    15      17      10      A12
1/6/2018    75      77      16      B34
1/7/2018    123     125     3       C56
1/8/2018    100     200     12      C56

如果您还没有按日期加入,那么添加不同的caldate / fn组合会给您重复。你也必须按日期加入,对吗?

答案 3 :(得分:0)

您获得的行数多于预期的原因是因为连接条件。如果你想在每天为每个fn找到新郎和房间,你也可以添加加入条件的日期:

Select table1.caldate as date,
  sum(grooms) as g,
  sum(rooms) as r,
  sum(pickup) as p
  from table1
  inner join table2 on  table1.fn      = table2.fn
                    and table1.caldate = table2.roomdate