2013-02-12 3 views
-1

У меня есть 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 

ответ

1

Возможно, что-то подобное может быть полезным:

SELECT 
    re.ResourceID, 
    re.ResourceName, 
    ch.UserID, 
    AmountCharged = SUM(ch.TotalAmount) 
FROM 
    Location lo 
    CROSS JOIN Charge ch 
    CROSS APPLY (
    SELECT DATEDIFF(DAY, lo.StartDate, ch.ChargeDate) % lo.DaysInRoster 
) x (RosterDay) 
    INNER JOIN 
    [Resource] re 
    LEFT JOIN Roster ro 
    ON 
     ro.RosterDay = x.RosterDay 
     AND ch.ChargeDate BETWEEN ro.StartDate 
     AND ro.RecourceID = re.ResourceID 
    LEFT JOIN SpecialRoster sr 
    ON 
     sr.RosterDate = ch.ChargeDate 
     AND sr.RecourceID = re.ResourceID 
    ON 
    ch.UserID = ISNULL(sr.UserID, ro.UserID) 
GROUP BY 
    re.ResourceID, 
    re.ResourceName, 
    ch.UserID 
WHERE 
    lo.LocationID = @LocationID 
    AND ch.ChargeDate BETWEEN ... 
; 

В приведенном выше сценарии предполагается, что все значения DateTime в действительности только даты.

Кроме того, я был несколько удивлен, не обнаружив связь между Location и любой из других указанных таблиц. Если есть один, и вы просто забыли упомянуть об этом, сообщите мне, если вам нужна помощь с включением в сценарий необходимых условий.

+0

Спасибо, это выглядит лучше, чем решение, которое я написал в среднем. Я дам это попробовать завтра и дам вам знать, как я пойду. Большое спасибо за ваше время. Таблица местоположений связана с Charge, но я пропустил ее и около 120 других полей, чтобы упростить вопрос, для всех целей и задач - идентификатор locationID всегда загружается инструментом отчетности. Ура! – Molloch