У меня есть 5 таблиц: местоположение, стоимость, ресурс, реестр и специальный ролик.Получить идентификатор пользователя из таблицы RosterResource Таблица
CREATE TABLE Location(
LocationID int identity,
StartDate datetime,
DaysInRoster int)
CREATE TABLE Charge(
ChargeID int identity,
TotalAmount money,
ChargeDate datetime,
UserID int)
CREATE TABLE [Resource](
ResourceID int identity,
ResourceName varchar(100))
CREATE TABLE Roster(
RosterDay int,
ResourceID int,
StartDate datetime,
EndDate datetime,
UserID int)
CREATE TABLE SpecialRoster(
RosterDate datetime,
ResourceID int,
UserID int)
Мне нужно создать отчет, который показывает сумму Charge.TotalAmount в разные дни, по ResourceID.
Charge имеет только UserID, но правила довольно просты: Если дата и RESOURCEID находится в SpecialRoster, идент берется из SpecialRoster Если нет, то Идентификатор_пользователь для ресурса и RosterDay на дату берутся от тока в токе в то время
В принципе, мне нужно сопоставить ResourceID, через UserID от Roster или SpecialRoster, для зарядки.
RosterDay это текущий день реестра, и может быть вычислен с места, где RosterDay = DateDiff(day, Location.RosterStartDate, GetDate()) % Location.DaysInRoster
то есть, модуль разности между началом всего списка в этом месте, с числом дней в реестре.
Я написал функцию, чтобы сделать это:
CREATE FUNCTION dbo.GetRosteredUser
(
@ResourceID int,
@Date datetime,
@LocationID int
)
RETURNS int
AS
BEGIN
DECLARE @UserID int
DECLARE @RosterOffset int
Select @UserID = UserID from SpecialRoster Where ResourceID = @ResourceID and RosterDate = @Date
If @UserID is NOT NULL
return @UserID
else
Select @RosterOffset = DATEDIFF(day, StartDate, @Date) % DaysInRoster
from Location Where LocationID = @LocationID
Select @UserID = UserID from Roster Where ResourceID = @ResourceID and RosterDay = @RosterOffset
and (@Date between StartDate and EndDate or @Date > StartDate and EndDate is NULL)
return @UserID
END
GO
Но функция не велика, как это происходит медленно, и только позволяет отчет, который будет работать в течение одного дня в то время:
Select a.ResourceID, Name, a.UserID, Sum(c.TotalAmount) as AmountCharged
from Charge c
left outer join (
Select ResourceID, Name,
dbo.GetUserByResourceDate(ResourceID, '1/FEB/2013', 1) as UserID
from [Resource]) a
on c.UserID = a.UserID
Where ChargeDate between '1/FEB/2013' and '2/FEB/2013'
group by a.ResourceID, Name, a.UserID
Есть ли лучший способ сделать это? Пользователь захочет запустить это, чтобы сравнить производительность ресурса в течение определенного периода времени. например:
Date ResourceID Name UserID TotalAmount
01/FEB/2013 1 Sales1 22 $1024
02/FEB/2013 1 Sales1 11 $1454
03/FEB/2013 1 Sales1 14 $1900
04/FEB/2013 1 Sales1 23 $3045
Спасибо, это выглядит лучше, чем решение, которое я написал в среднем. Я дам это попробовать завтра и дам вам знать, как я пойду. Большое спасибо за ваше время. Таблица местоположений связана с Charge, но я пропустил ее и около 120 других полей, чтобы упростить вопрос, для всех целей и задач - идентификатор locationID всегда загружается инструментом отчетности. Ура! – Molloch