Sql Server:如何显示每个子记录的所有主记录?

时间:2012-02-29 20:23:08

标签: sql sql-server sql-server-2008 sql-server-2005 tsql

我有两张桌子,一张是主人,另一张是小孩。

像这样的东西

站长:

Id  Description
1   Apple
2   Banana
3   Grape
4   Orange

子:

Id  MasterFk    Date            Bought
1   2           01/Jan/2012     2
2   1           05/Jan/2012     4
3   4           06/Jan/2012     8
4   3           06/Jan/2012     10
5   1           09/Jan/2012     3
6   3           10/Jan/2012     5

现在我需要这种格式的数据

Date              Description    Bought
01/Jan/2012       Apple            0
01/Jan/2012       Banana          2
01/Jan/2012       Grape            0
01/Jan/2012       Orange          0
05/Jan/2012       Apple            1
05/Jan/2012       Banana          0
05/Jan/2012       Grape            0
05/Jan/2012       Orange          0
06/Jan/2012       Apple            0
06/Jan/2012       Banana          0
06/Jan/2012       Grape            10
06/Jan/2012       Orange          8
...

表示所有主数据都应包含在每个日期的结果中,如果子项中没有相应的数据,则会显示默认值(0)。

请帮忙

4 个答案:

答案 0 :(得分:3)

好的,假设您的Child表中只有一条记录对一天购买的总数进行分组,那么您可以这样做:

SELECT Dates.[Date], M.Description, ISNULL(C.Bought,0) Bought
FROM MasterTable M
CROSS JOIN (SELECT DISTINCT [Date] FROM ChildTable) Dates
LEFT JOIN ChildTable C
ON M.Id = C.MasterFk AND Dates.[Date] = C.[Date]
ORDER BY Dates.[Date], M.Description, C.Bought

如果您每天只能获得一份水果记录,请执行以下操作:

SELECT Dates.[Date], M.Description, SUM(ISNULL(C.Bought,0)) Bought
FROM MasterTable M
CROSS JOIN (SELECT DISTINCT [Date] FROM ChildTable) Dates
LEFT JOIN ChildTable C
ON M.Id = C.MasterFk AND Dates.[Date] = C.[Date]
GROUP BY Dates.[Date], M.Description
ORDER BY Dates.[Date], M.Description

答案 1 :(得分:1)

SELECT Dates.date, m.description, ISNULL(c.bought,0)
FROM Master m
CROSS JOIN (SELECT DISTINCT date FROM Child) Dates 
LEFT JOIN Child c ON c.MasterFK = m.Id and c.date = Dates.date
ORDER BY Dates.date

答案 2 :(得分:0)

这将是“正常”的方式,但它不会显示0次购买的行:

Select c.date, m.description, c. bought
from Master m join Child c on m.id=c.masterid
order by c.date

如果你真的需要那些行,那么选项是有一个“日期”表(或任何其他可以显示间隔中所有日期的结构 - 我曾经创建了一个过程,它接收了2个日期作为参数并返回了一个结果集它们之间的所有日期,没有周末),并将此结构与前一个选择一起加入,如下所示:

Select d.date, m.description, c. bought
from Date D left join Child C on D.date=c.date join Master m on m.id=c.masterid
order by d.date

答案 3 :(得分:0)

您应该与所有可能的产品交叉加入所有可能的日期,然后选择已购买的数量(如果有的话)。

假设表定义:

create table Master (id int, description char(10));

insert into Master (id, description)
values (1, 'Apple'), (2, 'Banana'), (3, 'Grape'), (4, 'Orange');

create table Detail (id int, masterId int, buyDate date, bought int);

insert into Detail (id, masterId, buyDate, bought)
values (1, 3, '01/Jan/2012',     2),
   (2, 1, '05/Jan/2012',     4),
   (3, 3, '05/Jan/2012',     8),
   (4, 4, '09/Jan/2012',     10);

使用:

select BuyDates.BuyDate, M.description, 
       coalesce((select bought from Detail D
                 where D.buyDate = BuyDates.buyDate and M.id = D.masterId), 0)
from (select distinct buyDate from Detail) BuyDates
cross join Master M;