2016-06-23 1 views
0

Борьба за концептуализацию этого запроса. Любая помощь будет оценена.Запрос Sql для извлечения данных в описанном формате

Dataset

Таблица: Аудит

Date |Action |PackageId 
1/1/15 |Active |1 
1/2/15 |DeActive|1 
11/3/16|Update |2 
12/3/16|Update |2 
13/3/16|Update |2 
14/3/16|Update |2 

Таблица: Пакет

Id|Name 
1 |package1 
2 |package2 

Таблица: Пункт

Id|ItemName|PackageId 
1 | item1 |1 
2 | item2 |1 
3 | item3 |1 
4 | item4 |2 
5 | item5 |2 

Взаимосвязь между этими таблицами является Audit.PackageID Is foreign key to Package.Id and Item.PackageId is foreign key to Pacakge.id

Для приведенных выше данных, я хочу, чтобы сгенерировать отчет, как этот

Package.Name|Item.ItemName|Audit.Date|Audit.Action 
package1 | item1  | 1/1/15 | Active 
package1 | item2  | 1/2/15 | DeActive 
package1 | item3  | NULL  | NULL 
package2 | item4  | 11/3/16 | update 
package2 | item5  | 12/3/16 | update 
package2 | NULL  | 13/3/16 | update 
package2 | NULL  | 14/3/16 | update 

в основном информация о товаре или аудит не дублируется и информационный пакет дублируется, если информационный элемент/аудит больше, чем число упаковок. Надеюсь, это имеет смысл.

Мне в основном нужно написать хранимую процедуру, которая вернет набор данных, как описано выше. Этот результат затем подается в анализатор отчетов, который заменит все NULL на blanks и сгенерирует отчет Excel. База данных SQL-Server-2000.

+0

Основываясь на данных вашего образца, как вы получите '12/3/16' в окончательном отчете ... также можете создать образец на http://sqlfiddle.com/ – Hackerman

+0

@Hackerman: Исправлены данные для включить '12/3/16 в аудит'. Будет создавать образец на скрипке и отправить ссылку –

+0

Спасибо @Mukul, с образцовыми данными я собираюсь получить правильный запрос в кратчайшие сроки! – Hackerman

ответ

1

По существу, вы пытаетесь сделать два отчета в одной таблице; у вас есть отчет о пакетах и ​​отчет об аудите пакета. Обычно вы делаете это на уровне отчетности с суб-отчетами.

Если вам нужно сделать это таким образом, вам нужно будет сгенерировать два отчета в таблицах с ключами, чтобы их можно было объединить. Поскольку вы используете SQL 2000, у вас нет функции ROW_NUMBER() для генерации некоторых порядковых номеров ... что является неудачным. Поэтому вместо этого вы можете создавать временные таблицы с увеличивающимися полями идентификаторов.

Вот схема вы предоставили:

CREATE TABLE #Audit 
    (Date varchar(7), Action varchar(8), PackageId int) 
; 

INSERT INTO #Audit 
    (Date, Action, PackageId) 
VALUES 
    ('1/1/15', 'Active', 1), 
    ('1/2/15', 'DeActive', 1), 
    ('11/3/16', 'Update', 2), 
    ('12/3/16', 'Update', 2), 
    ('13/3/16', 'Update', 2), 
    ('14/3/16', 'Update', 2) 
; 

CREATE TABLE #Package 
    (Id int, Name varchar(8)) 
; 

INSERT INTO #Package 
    (Id, Name) 
VALUES 
    (1, 'package1'), 
    (2, 'package2') 
; 

CREATE TABLE #Item 
    (Id int, ItemName varchar(5), PackageId int) 
; 

INSERT INTO #Item 
    (Id, ItemName, PackageId) 
VALUES 
    (1, 'item1', 1), 
    (2, 'item2', 1), 
    (3, 'item3', 1), 
    (4, 'item4', 2), 
    (5, 'item5', 2) 
; 

Затем создайте еще две таблицы, чтобы держать две свои отдельные отчеты и заселить их. Таблицы отчета нуждаются в поле идентификатора так, что он генерирует уникальный номер для каждой строки в отчете:

create table #PackageItemsReport 
( PackageItemsId int identity(1,1), 
    PackageId int, 
    PackageName varchar(8), 
    ItemName varchar(5) 
) 

insert into #PackageItemsReport 
(PackageId,PackageName,ItemName) 
select #Package.Id, #package.Name, #item.ItemName 
from #Package 
join #Item 
on #Package.Id = #item.PackageId 
order by #Package.Id, #item.ItemName 

create table #PackageAuditReport 
( PackageAuditId int identity(1,1), 
    PackageID int, 
    PackageName varchar(8), 
    AuditDate varchar(7), 
    AuditAction varchar(8) 
) 

insert into #PackageAuditReport 
(PackageID,PackageName,AuditDate,AuditAction) 
select #Package.Id, #Package.Name, #Audit.Date, #Audit.Action 
from #Package 
join #Audit 
on #Audit.PackageId = #Package.Id 
order by #Package.Id, #Audit.Date, #Audit.Action 

Затем вам нужно соединить два отчета вместе с использованием идентификатора пакета и номера строк сгенерированного:

select ISNULL(PackageItemsReport.PackageName, PackageAuditReport.PackageName) Name, 
    ItemName, 
    AuditDate, 
    AuditAction 
from 
(
    select #PackageItemsReport.*, PackageItemsId - MinPackageItemsId RowNum 
    from #PackageItemsReport 
    join 
    (
    select PackageID, MIN(PackageItemsId) MinPackageItemsId 
    From #PackageItemsReport 
    group by PackageID 
    ) MinPackageItemsIds 
    on #PackageItemsReport.PackageID = MinPackageItemsIds.PackageID 
) PackageItemsReport 
full join 
(
    select #PackageAuditReport.*, PackageAuditId - MinPackageAuditId RowNum 
    from #PackageAuditReport 
    join 
    (
    select PackageID, MIN(PackageAuditId) MinPackageAuditId 
    From #PackageAuditReport 
    group by PackageID 
    ) MinPackageAuditIds 
    on #PackageAuditReport.PackageID = MinPackageAuditIds.PackageID 
) PackageAuditReport 
on PackageItemsReport.PackageID = PackageAuditReport.PackageID 
    and PackageItemsReport.RowNum = PackageAuditReport.RowNum 
order by ISNULL(PackageItemsReport.PackageID, PackageAuditReport.PackageID), 
    ISNULL(PackageItemsReport.RowNum, PackageAuditReport.RowNum) 

Это грязно ... слава богу, после добавления SQL Server 2000 была добавлена ​​функция ROW_NUMBER(). Теперь это намного проще.

+0

Спасибо Брайан. Я попробовал это с помощью тестовых данных и отлично работает. Попробуем с фактической таблицей и набором данных завтра. Должно быть хорошо, хотя. –

+0

Протестировано и работает хорошо. Большое спасибо. веселит. –

Смежные вопросы