Сервер SQL: Как отобразить все основные записи для каждой дочерней записи? - PullRequest
0 голосов
/ 01 марта 2012

У меня есть две таблицы: одна - главная, другая - дочерняя.

Примерно так

Master:

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 ]

3 голосов
/ 01 марта 2012

Хорошо, при условии, что у вас будет только одна запись в вашей дочерней таблице, которая группирует общее количество купленных за день, вы можете сделать это:

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 голос
/ 01 марта 2012
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
0 голосов
/ 01 марта 2012

Вы должны перекрестно объединить все возможные даты со всеми возможными продуктами, а затем выбрать существующие количества закупок, если таковые имеются для каждой комбинации.

Предполагая определения таблиц:

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;
0 голосов
/ 01 марта 2012

это был бы "нормальный" способ, но он не будет отображать строки с 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...