Это значения, которые мне нужно вернуть из хранимой процедуры:
Description
Week 1 Usage
Week 2 Usage
Usage Variance
Week 1 Price
Week 2 Price
Price Variance
% of Price Variance
Три поля с «Отклонением» в названии являются вычисляемыми полями на основе других значений, а разделы «Неделя» должны рассчитываться на основе параметров даты. Таким образом, фактические (наиболее важные) поля, которые находятся в таблицах базы данных:
Description
Usage
Price
InvoiceDate
Параметры, предоставляемые пользователем:
Unit
DateBegin
DateEnd
Переменные, которые, я думаю, мне нужно будет объявить в хранимой процедуре:
DECLARE
@Week1Begin datetime,
@Week1End datetime,
@Week2Begin datetime,
@Week2End datetime,
@Week1Usage varchar(30),
@Week2Usage varchar(30),
@Week1Price varchar(30),
@Week2Price varchar(30),
@UsageVariance varchar(30),
@PriceVariance varchar(30),
@PercentageOfPriceVariance varchar(30)
Week1Begin
и Week1End
должны быть вычислены на основе значения, предоставленного пользователем в параметре DateBegin
(например, если DateBegin
будет 27.12.15, Week1Begin
будет 27.12.2015, а Week1End
будет 02.01.2016) ;
Week2Begin
и Week2End
будут похожи, но их период может быть менее семи дней, а если дольше, то максимум 7 дней (Week2End
будет "сокращаться" до предыдущей даты по мере необходимости).
Таким образом, несмотря на то, что выполняется много вычислений, необработанных данных довольно мало. В основном это четыре поля, упомянутые выше (Описание, Использование, Цена и Дата счета), которые доступны из таблицы InvoiceDetail
.
Моя самая большая дилемма заключается в том, что большая часть этих данных возвращается из существующей хранимой процедуры, которую лучше скопировать и расширить, но я никоим образом не являюсь экспертом по SQL - я могу писать простые операторы SELECT
и UPDATE
и т. д., но танцевать с временными таблицами и такими реляционными оборотами мне не по силам.
Таким образом, создание новой хранимой процедуры на основе существующей кажется опасным; OTOH, интересно, можно ли получить нужные мне данные, используя довольно минимальную хранимую процедуру со сложным оператором запроса, содержащим несколько подзапросов.
Опять же, сложный SQL ни в коем случае не является моей сильной стороной, поэтому я могу быть «далеким», но вот мой псевдо-SQL:
CREATE Procedure [dbo].[myFunkySP]
@Unit varchar(25),
@BegDate datetime,
@EndDate datetime
As
// Create a mostly-empty-for-now temp table
Select Description,
Week1Begin,
Week1End,
Week2Begin,
Week2End,
Week1Usage,
Week2Usage,
Week1Price,
Week2Price,
UsageVariance,
PriceVariance
PercentageOfPriceVariance
Into #TempItems
From InvoiceDetail Ind
Where Ind.Unit = @Unit
and Ind.InvoiceDate Between @BegDate and @EndDate
begin
Update #TempItems set
Week1Begin = // val from@BegDate
Week1End = // do some date math to determine; maybe a Function called GetEndOfWeek(Week1Begin)?
Week2Begin = // do some date math to determine (1 day beyond Week1End val)
Week2End = // val from@EndDate
Week1Usage = SELECT SUM(USAGE) FROM InvoiceDetail WHERE UNIT = @UNIT, DATE BETWEEN Week1Begin AND Week1End
Week2Usage = SELECT SUM(USAGE) FROM InvoiceDetail WHERE UNIT = @UNIT, DATE BETWEEN Week2Begin AND Week2End
Week1Price = SELECT SUM(PRICE) FROM InvoiceDetail WHERE UNIT = @UNIT, DATE BETWEEN Week1Begin AND Week1End
Week2Price = SELECT SUM(PRICE) FROM InvoiceDetail WHERE UNIT = @UNIT, DATE BETWEEN Week2Begin AND Week2End
UsageVariance = (Week2Usage - Week1Usage)
PriceVariance = (Week2Price - Week1Price)
PercentageOfPriceVariance = (PriceVariance div week2Price)
// now select * from the temp table to return everything?
В противном случае (если вышеописанное не сработает или невыполнимо), я подумал, что мне, возможно, придется выполнить запрос 9-X-Uglier-than-a-of-butts, загрязненный подзапросами beaucoup, что-то вроде:
SELECT DESCRIPTION,
(SELECT SUM(USAGE) FROM InvoiceDetail
WHERE UNIT = @UNIT, InvoiceDate BETWEEN :firstWeekBegin AND :firstWeekEnd as Week1Usage),
(SELECT SUM(USAGE) FROM InvoiceDetail
WHERE UNIT = @UNIT, InvoiceDate BETWEEN :secondWeekBegin AND :secondWeekEnd as Week2Usage),
SELECT PRICE FROM InvoiceDetail
WHERE UNIT = @UNIT, InvoiceDate = firstWeekBegin as Week1Price),
(SELECT PRICE FROM InvoiceDetail
WHERE UNIT = @UNIT, InvoiceDate = secondWeekBegin as Week2Price),
FROM InvoiceDetail
WHERE UNIT = @UNIT, InvoiceDate BETWEEN @BEGDATE AND @ENDATE ORDER BY PRODUCTS
Скажи, что это не так, Джо!
Даже если этот запутанный запрос работает, он все равно не дает мне расчетных значений, которые мне нужны (UsageVariance, PriceVariance и PercentageOfPriceVariance).
Итак, что мне нужно сделать, чтобы создать хранимую процедуру, которая будет возвращать нужные мне результаты?
</rant>
- person marc_s   schedule 13.01.2016