Форум: "Базы";
Текущий архив: 2005.10.02;
Скачать: [xml.tar.bz2];
ВнизSQL запрос Найти похожие ветки
← →
AndrewK (2005-08-17 14:38) [0]Доброго времени суток, господа!
Зашел в тупик - выведите, пожалуйста.
У меня есть три выборки данных:
1 выборка:
Date
----------
01.07.2005
02.07.2005
03.07.2005
04.07.2005
05.07.2005
...
15.07.2005
2 выборка:
Document_ID Document_Data Quantity
---------------------------------------------------
1 01.07.2005 10
2 02.07.2005 15
3 03.07.2005 3
3 выборка:
Product_ID Document_Data Quantity
---------------------------------------------------
5 01.07.2005 7
6 02.07.2005 4
7 05.07.2005 5
8 15.07.2005 81
Надо получить SQL запросом таблицу следующего вида:
Date Product_ID Quantity1 Quantity2
-------------------------------------------------------------
01.07.2005 1 10 7
02.07.2005 1 15 4
03.07.2005 1 3 0
04.07.2005 1 0 0
05.07.2005 1 0 5
...
15.07.2005 1 0 81
Посоветуйте, как это сделать.
← →
Fay © (2005-08-17 14:45) [1]2 AndrewK (17.08.05 14:38)
Ничё не понял
← →
Sergey13 © (2005-08-17 14:48) [2]Приведи не "выборки" непонятные, а структуру таблиц.
← →
AndrewK (2005-08-17 14:58) [3]Перечитываю вопрос и понимаю, что сам ничего не понимаю. :(
Попробую объяснить на словах. У меня есть выборка с датами и есть две выборки, собранные по накладным в базе. В выборках представляют собой строки (Дата - Количество). Даты в этих выборках могут отличаться, что показано в первом вопросе.
Когда пытаюсь собрать все через join к первой таблице, то получается, что некоторые записи дублируются.
Получается примерно такая выборка, где в позиции, которые должны быть пустыми вставляется что-то:
Date Product_ID Quantity1 Quantity2
-------------------------------------------------------------
01.07.2005 1 10 7
02.07.2005 1 15 4
03.07.2005 1 3 0
05.07.2005 1 3 5
...
15.07.2005 1 3 81
Ответ наверное в том, чтобы использовать еще один параметр, желательно обеспечивающий точное взаимоотношение, для присоединения, кроме даты. Пытаюсь его найти.
← →
Sergey13 © (2005-08-17 15:15) [4]СКЛ-запрос оперирует с таблицами, а не с выборками (я тебе по одной таблице столько выборок сделаю, что мало не покажется). С выборками крутись на клиенте через циклы.
← →
Nikolay M. © (2005-08-17 16:17) [5]
> Sergey13 © (17.08.05 15:15) [4]
> СКЛ-запрос оперирует с таблицами, а не с выборками
С терминологией и изложением своих мыслей у автора, конечно, напряг. Но что мешает в MS SQL написатьSELECT *
FROM
(SELECT * FROM tab1) a,
(SELECT * FROM tab2) b
? Чем не выборка из выборки? :)
> AndrewK
Если из всей этой каши я хоть что-то понял, тогда, может быть, так?SELECT
Date,
(SELECT Quantity1 FROM tab2 WHERE tab1.Date = tab2.Date),
(SELECT Quantity2 FROM tab3 WHERE tab1.Date = tab3.Date)
FROM
tab1
?
Даты в tab1, tab2 и tab3 подразумеваются уникальными для каждой таблицы.
← →
Sergey13 © (2005-08-17 16:23) [6]2[5] Nikolay M. © (17.08.05 16:17)
А что мешает так?SELECT *
FROM
(SELECT date FROM tab1) a,
(SELECT Document_ID, Document_Data, Quantity FROM tab1) b
(SELECT Product_ID, Document_Data, Quantity FROM tab1) с
8-)
← →
Nikolay M. © (2005-08-17 16:31) [7]
> Sergey13 © (17.08.05 16:23) [6]
> А что мешает так?
То, что автор, скорее всего, делает "выборки" :) из разных таблиц.
Да и вряд ли ему нужно декартово произведение трех "выборок" :)
← →
Sergey13 © (2005-08-17 16:35) [8]2[7] Nikolay M. © (17.08.05 16:31)
> То, что автор, скорее всего, делает "выборки" :) из разных таблиц.
Домыслы все это. 8-)
← →
Nikolay M. © (2005-08-17 16:44) [9]
> Sergey13 © (17.08.05 16:35) [8]
> Домыслы все это. 8-)
Конечно. Собссно, ждем автора на сцену :)
← →
AndrewK (2005-08-17 18:25) [10]Автор на сцене: :)
Вот кусок базы данных:
CREATE TABLE [dbo].[BarCode] (
[Date] [smalldatetime] NOT NULL ,
[Number] [int] NOT NULL ,
[FurnitureSetId] [int] NOT NULL ,
[PacketId] [int] NOT NULL ,
[Code] [char] (30) COLLATE SQL_Latin1_General_CP1251_CI_AS NOT NULL ,
[Status] [smallint] NOT NULL ,
[Organization] [int] NOT NULL
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[CheckArea] (
[Id] [int] NOT NULL ,
[Name] [char] (128) COLLATE SQL_Latin1_General_CP1251_CI_AS NOT NULL ,
[Note] [char] (128) COLLATE SQL_Latin1_General_CP1251_CI_AS NULL ,
[Options] [int] NULL ,
[Organization] [int] NOT NULL
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[CheckPost] (
[Id] [int] NOT NULL ,
[Name] [char] (128) COLLATE SQL_Latin1_General_CP1251_CI_AS NOT NULL ,
[Note] [char] (128) COLLATE SQL_Latin1_General_CP1251_CI_AS NULL ,
[Computer] [char] (64) COLLATE SQL_Latin1_General_CP1251_CI_AS NULL ,
[CheckAreaId] [int] NOT NULL ,
[Debet] [smallint] NOT NULL ,
[Status] [int] NOT NULL ,
[Archive] [int] NULL ,
[OrderCode] [int] NULL ,
[OPTIONS] [int] NULL ,
[Organization] [int] NOT NULL
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[Document] (
[Id] [int] NOT NULL ,
[Date] [smalldatetime] NOT NULL ,
[Note] [char] (128) COLLATE SQL_Latin1_General_CP1251_CI_AS NULL ,
[CheckPostId] [int] NOT NULL ,
[ClientId] [int] NULL ,
[StorekeeperId] [int] NULL ,
[BrigadeLeaderId] [int] NULL ,
[Organization] [int] NOT NULL
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[FurnitureSet] (
[Id] [int] NOT NULL ,
[Name] [char] (128) COLLATE SQL_Latin1_General_CP1251_CI_AS NOT NULL ,
[GOST] [char] (20) COLLATE SQL_Latin1_General_CP1251_CI_AS NULL ,
[PacketQuantity] [int] NOT NULL ,
[Note] [char] (128) COLLATE SQL_Latin1_General_CP1251_CI_AS NULL ,
[Weight] [real] NULL ,
[RusCode] [char] (10) COLLATE SQL_Latin1_General_CP1251_CI_AS NULL ,
[Status] [smallint] NULL ,
[NoteEx] [char] (128) COLLATE SQL_Latin1_General_CP1251_CI_AS NULL ,
[Organization] [int] NOT NULL
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[Label] (
[Date] [smalldatetime] NOT NULL ,
[DocumentId] [int] NOT NULL ,
[OrderCount] [int] NOT NULL ,
[Code] [char] (30) COLLATE SQL_Latin1_General_CP1251_CI_AS NOT NULL ,
[Product] [char] (30) COLLATE SQL_Latin1_General_CP1251_CI_AS NOT NULL ,
[CheckAreaId] [int] NOT NULL ,
[CheckPostId] [int] NOT NULL ,
[Debet] [smallint] NOT NULL ,
[Organization] [int] NOT NULL
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[Packet] (
[Id] [int] NOT NULL ,
[FurnitureId] [int] NOT NULL ,
[Number] [char] (5) COLLATE SQL_Latin1_General_CP1251_CI_AS NOT NULL ,
[Name] [char] (128) COLLATE SQL_Latin1_General_CP1251_CI_AS NOT NULL ,
[PackPostId] [int] NOT NULL ,
[FormatId] [int] NOT NULL ,
[Weight] [real] NULL ,
[Pile] [int] NULL ,
[Organization] [int] NOT NULL
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[ResourceM] (
[Date] [smalldatetime] NOT NULL ,
[Number] [int] NOT NULL ,
[FurnitureSetId] [int] NOT NULL ,
[PacketId] [int] NOT NULL ,
[AccountUnit] [char] (30) COLLATE SQL_Latin1_General_CP1251_CI_AS NOT NULL ,
[CheckAreaId] [int] NOT NULL ,
[Rest] [int] NOT NULL ,
[EntryDate] [smalldatetime] NOT NULL ,
[LastDate] [smalldatetime] NOT NULL ,
[Organization] [int] NOT NULL
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[Task] (
[Date] [smalldatetime] NOT NULL ,
[Number] [int] NOT NULL ,
[FurnitureSetId] [int] NOT NULL ,
[ColourId] [int] NOT NULL ,
[Quantity] [int] NOT NULL ,
[Shift] [smallint] NOT NULL ,
[Category] [char] (10) COLLATE SQL_Latin1_General_CP1251_CI_AS NULL ,
[Status] [int] NULL ,
[DoneDate] [smalldatetime] NULL ,
[Note] [char] (128) COLLATE SQL_Latin1_General_CP1251_CI_AS NULL ,
[Organization] [int] NOT NULL
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[TaskDetail] (
[Date] [smalldatetime] NOT NULL ,
[Number] [int] NOT NULL ,
[FurnitureSetId] [int] NOT NULL ,
[PacketId] [int] NOT NULL ,
[Quantity] [int] NOT NULL ,
[Organization] [int] NOT NULL
) ON [PRIMARY]
GO
База досталась в наследство от подрядчика, поэтому за структуру не критикуйте - я тут не при чем.
← →
MOA © (2005-08-17 18:31) [11]А сделать-то что надо?
← →
AndrewK (2005-08-17 18:33) [12]Сейчас. Готовлю описание.
← →
AndrewK (2005-08-17 18:45) [13]Описание:
Не знаю, сможет ли это помочь, так как даже общение в живую с этой базой дается довольно трудно, но попробую...
Вся база предназначена для системы учета движения продукции на складах с помощью сканеров штрихкодов.
CheckArea - зоны учета (склады), объединяют в себе несколько точек контроля, хранящиеся в CheckPost (например: приход, расход, возврат).
FurnitureSet - номенклатура, Packet - пакеты из которых номенклатура состоит.
Task - сменные задания (говориться сколько каких изделий запустить в производство и для каких рассчитать и напечатать штрихкод)
TaskDetail - сменное задание разбитое до пакетов.
BarCode - таблица в которую записываются сформированные штрихкоды и которые потом система разрешает использовать в работе.
Document - накладная на прохождение пакетов со штрихкодами через контрольную точку.
Label - перечень штрихкодов, которые прошли через точку учета по документу.
ResourceM - срез данных, показывающий остатки продукции на зоне учета. Теоретически должна была ускорять получение отчетов,
но на практике - сомневаюсь.
Записей в базе более трех миллионов в таблице Label.
Что надо сделать:
Есть задача построить по этому монстру отчет, который покажет как разошлось конкретное сменное задание по разным контрольным точкам.
Например, в Task зарегистрировано сменное задание на изделие, в TaskDetail оно расписывается по пакетам, допустим в изделии три пакета.
Количество изделий 100 штук. В таблице BarCode формируется 300 записей с уникальными штрихкодами (поле Code).
Структура складов - два склада (две записи в CheckArea). В каждой зоне учета по две точки "Приход" и "Расход" (CheckPost).
Пакеты изготовили, наклеили на них этикетки и сдали на склад. Склад просканировал пакеты и провел их через точку "Приход" первого склада.
При этом кладовщик сформировал документ (Document) на нужной контрольной точке и записал в Label все, что он насканировал. Затем те же
операции повторяются на других точках. Количество пакетов может быть разным, даты документов и клиенты, которым отгружается то же.
Примерная форма отчета (рисую как на будет для печати):
--------------------------------------------------------------------------------
Изделие Склад 1 Склад 2
Пакет
Дата Приход Расход Приход Расход
--------------------------------------------------------------------------------
Изделие 1
Пакет 1
01.01.2005
Петров 10 15 0 10
Сидоров 5 0 0 0
"Не указан" 20 10 50 50
Пакет 2
...
--------------------------------------------------------------------------------
← →
AndrewK (2005-08-17 18:50) [14]Могу получить отчет по одной контрольной точке
CREATE FUNCTION
bc_GetTaskHistory (
@TaskDate datetime,
@TaskNumberList char(10),
@CheckPost_ID int
)
RETURNS TABLE
AS
return
select
bc.FurnitureSetId fsId,
bc.PacketID pkID,
cl.Name clnName,
bc.Number tskNum,
lb.Date lbDate,
count(lb.Code) Qnt
from
BarCode bc
inner join Label lb on lb.Code = bc.Code
inner join Document dc on dc.id = lb.DocumentID and dc.Date = lb.Date
left join Client cl on cl.Id = dc.ClientId
where
bc.Date = @TaskDate
and
((@TaskNumberList = "#") or (CharIndex("#"+LTrim(RTrim(Str(bc.Number)))+"#", @TaskNumberList) > 0))
and
lb.CheckPostID = @CheckPost_ID
group by
bc.FurnitureSetId,
bc.Number,
lb.Date,
bc.PacketID,
cl.Name
Пробовал сделать отчет:
select
fs.Id,
fs.Name,
col.Id,
col.Name,
tsk.Quantity,
tsk.Number,
pk.Id,
pk.Number,
pk.Name,
lbl.Date,
ChPst1.lbDate Date1,
ChPst1.Qnt Quantity1,
ChPst1.clnName ClientName1,
ChPst2.lbDate Date2,
ChPst2.Qnt Quantity2,
ChPst2.clnName ClientName2,
ChPst3.lbDate Date3,
ChPst3.Qnt Quantity3,
ChPst3.clnName ClientName3,
ChPst4.lbDate Date4,
ChPst4.Qnt Quantity4,
ChPst4.clnName ClientName4
from
Task tsk
left join TaskDetail tskd on tskd.[Date] = tsk.[Date] and tskd.Number = tsk.Number and tskd.FurnitureSetId = tsk.FurnitureSetId
left join FurnitureSet fs on fs.Id = tsk.FurnitureSetId
left join Colour col on col.Id = tsk.ColourId
left join Packet pk on pk.Id = tskd.PacketId
left join BarCode bc on bc.Number = tsk.Number and bc.Date = tsk.Date
left join Label lbl on lbl.Code = bc.Code
left join dbo.bc_GetTaskHistory (@TaskDate, @TaskNumberList, 13) ChPst1 on -- СПХ произведено
ChPst1.fsId = fs.Id and
ChPst1.pkID = pk.Id and
ChPst1.tskNum = tsk.Number and
ChPst1.lbDate = lbl.Date
left join dbo.bc_GetTaskHistory (@TaskDate, @TaskNumberList, 14) ChPst2 on -- СПХ отгрузка на склад
ChPst2.fsId = fs.Id and
ChPst2.pkID = pk.Id and
ChPst2.tskNum = tsk.Number and
ChPst2.lbDate = lbl.Date
left join dbo.bc_GetTaskHistory (@TaskDate, @TaskNumberList, 3) ChPst3 on -- СГП прием
ChPst3.fsId = fs.Id and
ChPst3.pkID = pk.Id and
ChPst3.tskNum = tsk.Number and
ChPst3.lbDate = lbl.Date
left join dbo.bc_GetTaskHistory (@TaskDate, @TaskNumberList, 4) ChPst4 on -- СГП отгрузка
ChPst4.fsId = fs.Id and
ChPst4.pkID = pk.Id and
ChPst4.tskNum = tsk.Number and
ChPst4.lbDate = lbl.Date
where
tsk.Date = @TaskDate
and
((@TaskNumberList = "#") or (CharIndex("#"+LTrim(RTrim(Str(tsk.Number)))+"#", @TaskNumberList) > 0))
order by
fs.Name,
col.Name,
cast(pk.Number as int)
И ту начинается полная лажа.
Проблема в структуре базы данных. Повлиять на нее сейчас не могу.
P.S. Вряд ли смогу объяснить все более подробно.
← →
evvcom © (2005-08-18 08:38) [15]
> Nikolay M. © (17.08.05 16:17) [5]
> Sergey13 © (17.08.05 16:23) [6]
Любите вы делать селект из селекта там, где этого можно и не делать. :) Хотя автор изначально не привел этих простеньких запросов, поэтому оставалось только гадать. А в [10], [13] и [14], в такой объем даже не хочется вникать.
> AndrewK (17.08.05 18:45) [13]
> Изделие Склад 1 Склад 2
А если у тебя будет 10 или 20 складов? Ты их тоже в одну строчку растянешь? Мое имхо - неверный подход. Покажи те простые запросы, не обремененные кучей лишних полей, которые ты выполняешь и получаешь выборки из [0] и [3].
← →
Sergey13 © (2005-08-18 09:39) [16]2[15] evvcom © (18.08.05 08:38)
>Любите вы делать селект из селекта там, где этого можно и не делать. :)
Это не любовь. Это попытка показать разницу между таблицей и выборкой.
2 AndrewK
Нифига себе развернул вопрос! 8-)
Тут разбираться надо не меньше дня.
При диагональном прочтении условий мне кажется, что одним запросом не получится, или получится очень частное решение. Надо думать в сторону ХП или крос-отчетов. ИМХО разумеется.
← →
Nikolay M. © (2005-08-18 10:51) [17]
> evvcom © (18.08.05 08:38) [15]
> Любите вы делать селект из селекта там, где этого можно
> и не делать. :)
С какого потолка взят такой вывод?
> Sergey13 © (18.08.05 09:39) [16]
Ну дык я же говорил, что выборка будет не из одной таблицы :) Но чтоб настолько... Не, лично я умываю руки, мне и на работе хватает таких задачек.
← →
AndrewK (2005-08-18 15:48) [18]Спасибо за ответы и за участие.
Задача была успешно решена 17.08.2005 где-то в районе 21:00 вечера. Использовал временную таблицу для того, чтобы получить полный набор строк, которые могут быть в отчете, и к ней цеплял выборки из функций.
> evvcom ©
> если у тебя будет 10 или 20 складов? Ты их тоже в одну строчку
> растянешь? Мое имхо - неверный подход. Покажи те простые
> запросы, не обремененные кучей лишних полей, которые ты
> выполняешь и получаешь выборки из [0] и [3].
Знаю, что не верный, но кто-нибудь пробовал убедить бухгалтера или кладовщика в этом. Ему подай так и никак по другому. :(
Вот и пришлось заморачиваться с этим отчетом.
Еще раз всем спасибо!
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2005.10.02;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.004 c