#sql-server #stored-procedures
#sql-сервер #хранимые процедуры
Вопрос:
У меня есть две таблицы, одна Period
, а другая UserTarget
.
Period
таблица является:
QuarterNo StartDate EndDate
-----------------------------------------
1 2018-04-01 2018-06-30
2 2018-07-01 2018-09-30
3 2018-10-01 2018-12-31
4 2019-01-01 2019-03-31
UserTarget
таблица является :
USERID YEAR QTR AMOUNT
---------------------------------
akshay 2019 1 200
Прямо сейчас я беру qtr no из таблицы периодов. Теперь мне не нужно брать qtr no из таблицы периодов. Я хочу, чтобы он из хранимой процедуры на основе года был введен в usertarget
таблицу
Существующая хранимая процедура :
ALTER PROCEDURE [dbo].[GetQuarterlyTargetData]
@Userid VARCHAR(50)
AS
BEGIN
DECLARE @QuarterNumber VARCHAR(50)
DECLARE @SetTarget DECIMAL(10);
DECLARE @StartDate DATE
DECLARE @EndDate DATE
SELECT
@QuarterNumber = p.QuarterNo,
@SetTarget = AMOUNT
FROM
PERIOD p
LEFT OUTER JOIN
USERTARGETS s ON p.QuarterNo = s.QTR
WHERE
StartDate <= GETDATE() AND EndDate >= GETDATE()
SELECT
@StartDate = StartDate,
@EndDate = EndDate
FROM
PERIOD
WHERE
QuarterNo = @QuarterNumber
Из этой процедуры я получаю дату начала и дату окончания квартала, но я не хочу изменять таблицу периодов каждый раз, когда хочу проверить данные за предыдущие годы.
Комментарии:
1. Привет, я думаю, вам нужно добавить некоторый элемент управления годом и во второй запрос, например, так: случай, когда месяц (getdate) > 3, затем год = year (getdate) 1 еще год = year (getdate) end
2. @pascalsanchez Я удалил таблицу периодов, теперь у меня есть только целевая таблица пользователя, и в этом у меня есть год, исходя из которого я должен изменить свою процедуру
3. в этом случае все в порядке, хорошего дня
4. Я понятия не имею, что вы пытаетесь спросить. Можете ли вы попросить носителя английского языка помочь вам переписать ваш вопрос? Это не имеет никакого смысла.
Ответ №1:
Я полагаю, что термин, который вы ищете, — это финансовый год. Здесь год компании отличается от календарного года.
Обратите внимание, что многие люди рекомендуют использовать таблицу поиска вместо ее вычисления. Сопоставление дат может быть сложным для оптимизации SQL.
Вот один из способов сделать это. Вероятно, было бы неплохо ввести в табличную функцию поиск финансового года и квартала.
DECLARE @userTarget TABLE (UserId VARCHAR(20), Year INT, Quarter INT, Amount INT)
INSERT INTO @userTarget
VALUES
('akshay', 2018, 4, 150)
,('akshay', 2019, 1, 200)
SELECT
s.UserId
,s.Amount
,FY.FiscalYear
,FQ.FiscalQuarter
FROM
(
SELECT
--DATEFROMPARTS(2019, 2, 23)
GETDATE()
AS reportDate
) AS ReportDate
CROSS APPLY (
SELECT
CASE WHEN MONTH(ReportDate.reportDate) < 4 THEN YEAR(ReportDate.reportDate) - 1 -- Fiscal Year begins in April
ELSE YEAR(ReportDate.reportDate)
END AS FiscalYear
) AS FY
CROSS APPLY (
SELECT
DATEDIFF(QUARTER, DATEFROMPARTS(FY.FiscalYear, 4, 1), ReportDate.reportDate) 1 AS FiscalQuarter
) AS FQ
INNER JOIN @userTarget s
ON s.Year = FY.FiscalYear
AND s.Quarter = FQ.FiscalQuarter
Кроме того, будьте осторожны с конечными датами. last_day >= GETDATE()
не включает последний день. Возьмем в качестве примера конец последнего квартала, он будет вычислять его как '2019-03-31 00:00' >= '2019-03-31 08:20'
который является ложным, когда вы хотите, чтобы это было правдой.
Ответ №2:
Подумав, я пришел к этому решению
ALTER PROCEDURE [dbo].[Dashboard_GetQuarterlyTargetData]
@Userid varchar(50)
AS
Begin
DECLARE @QuarterNumber varchar(50)
DECLARE @SetTarget decimal(10);
DECLARE @AchievedTarget decimal(10);
DECLARE @TargetProgress decimal(10);
DECLARE @RemainingTarget decimal(10);
DECLARE @StartDate Date
DECLARE @EndDate Date
DECLARE @Year as int
Select @QuarterNumber = QTR,@Year=YEAR,@SetTarget=AMOUNT from USERTARGETS where USERID=@Userid
if(@QuarterNumber = 1)
begin
SELECT @StartDate = DATEFROMPARTS(@year,4,1), @EndDate=DATEFROMPARTS(@year,6,30)
End
else if(@QuarterNumber = 2)
begin
SELECT @StartDate = DATEFROMPARTS(@year,7,1), @EndDate=DATEFROMPARTS(@year,9,30)
End
else if(@QuarterNumber = 3)
begin
SELECT @StartDate = DATEFROMPARTS(@year,10,1), @EndDate=DATEFROMPARTS(@year,12,31)
End
else if(@QuarterNumber = 4)
begin
SELECT @StartDate = DATEFROMPARTS(@year,1,1), @EndDate=DATEFROMPARTS(@year,3,31)
End