1

私たちの会社で行っているラップトップの更新のための予約システムを書いています。どの日に利用可能なスロットがあるかを計算し、それらをカレンダー コントロールにレンダリングできるようにする必要があります (つまり、ある日に利用可能な日がある場合は選択可能であり、そうでない場合は選択できません。

ロジックは次のとおりです。

  • 技術者は 1 日に 3 台のラップトップを構築できます。
  • いつでも 1 人、2 人、または 3 人の技術者が対応可能です。
  • テーブルにはすでに行われた予約が保持されます

1 日あたりの利用可能なスロットの総数は (疑似コードで):

((laptops per day) * (technicians available)) - slots already booked

私の質問は、これを導出する最も効率的な方法は何ですか? 利用可能なスロットを含む日付のテーブルを返す関数を使用して、SQL 側で行うのが最善だと思います。(少なくとも 1 つのスロットが使用可能である限り、いくつあってもかまいません。)

これまでのところ、すべて頭に浮かぶことができます。私が立ち往生しているビットは、少し非効率的であるため、すべての可能な日付のテーブルを持ちたくないということです。私ができるようにしたいのは、現在から 3 か月先の日付範囲を効果的に反復し、そこから利用可能な日付を計算することです。

これは C# で行うこともできますが、可能な限り毎日 SQL サーバーにアクセスし続ける必要があるため、効率が悪いと思います。SQL側で行う方が良いようですが、この方法で可能な日付を反復する方法がわかりません。

これまでのソリューション

@Chris の方法を使用して、スロットの本が設定された最大値を超えない日付の範囲を取得できます。

DECLARE @startDate DATE
DECLARE @endDate DATE

SET @startDate = GETDATE()
SET @endDate = DATEADD(m,3,@startDate)
;
WITH dates(Date) AS 
(
    SELECT @startdate as Date
    UNION ALL
    SELECT DATEADD(d,1,[Date])
    FROM dates 
    WHERE DATE < @enddate
)

SELECT Date
FROM dates 
EXCEPT
SELECT date
        FROM tl_sb_booking
        GROUP BY date
        HAVING COUNT(date) < 3

これは、任意の最大 3 つの予約を設定しているだけです。次のステップは、技術者の可用性を追加することです!

4

3 に答える 3

2

この回答は、次のような質問の部分に対応しています。

MSSQL を使用している場合は、CTE が役立つ場合があります。次のような日付範囲コードを動的に生成するには、次のように使用できます。

DECLARE @startDate DATE
DECLARE @endDate DATE

SET @startDate = GETDATE()
SET @endDate = DATEADD(m,3,@startDate)
;
WITH dates(Date) AS 
(
    SELECT @startdate as Date
    UNION ALL
    SELECT DATEADD(d,1,[Date])
    FROM dates 
    WHERE DATE < @enddate
)

SELECT Date
FROM dates

その最後の SELECT を他のテーブルに結合して、その日付のデータを取得したり、計算を行ったりすることができます。

ただし、これが必ずしも最善の方法であるとは限りません。毎日何人のエンジニアが空いているかのリストを取得する何らかの方法があると仮定すると、他の日付を反復する必要はありません (それらの日付には空きがないことがわかっているため)。したがって、この目的のために次のようなものです:

SELECT count(1), Date
From EngineerWorkDays
GROUP BY Date
Where Date>= Getdate()
and Date < DATEADD(m,3,Getdate())

作業が行われている可能性のある日付のリストを返します。すでに割り当てられている作業を取得するための別の選択により、必要なすべてのデータが得られます。C# の表示コードでは、毎日反復処理を行い、関連するデータ (エンジニアが利用可能かどうか、人数、予約済みの作業量など) についてデータセットを確認できます。

また、これが共有アプリであるかどうかを忘れないでください。最初のクエリを実行した後に他の誰かが何かを予約した場合に備えて、何かを予約する前に日付にまだ空きがあることを確認してください.

于 2013-06-19T18:23:41.383 に答える
1

これを試して:

Select [DatesAvailable] From TableName
Where [DatesAvailable] Between BeginningDate And DateAdd(m, 3, BeginningDate) And
      SlotsAvailable > 0

これにより、次の 3 か月間に利用可能なスロットがある日付が表示されます...

于 2013-06-19T18:12:30.300 に答える
0

これを行う1つの方法は次のとおりです。

DECLARE @iToday As INT; SET @iToday = CAST(GetDate() As INT);
DECLARE @iDays As INT;  SET @iDays = 90;

WITH cte_0to9 As
(
    Select 0 As Num UNION ALL Select 1 UNION ALL Select 2 UNION ALL Select 3
    UNION ALL Select 4 UNION ALL Select 5 UNION ALL Select 6 UNION ALL Select 7
    UNION ALL Select 8  UNION ALL Select 9
)
, cte_0to99 As
(
    SELECT  (Tens.Num * 10) + Ones.Num As Num
    FROM        cte_0to9 As Ones
    CROSS JOIN  cte_0to9 As Tens
)
, cteDays As 
(
    SELECT  CAST(@iToday + Num As DATETIME) As PossibleDate
    FROM    cte_0to99
    WHERE   Num <= @iDays
)
, cteTechnicianUtilization As
(
    SELECT  t.Technician,
            d.PossibleDate,
            (Select COUNT(*) From Bookings b
             Where b.Technician = t.Technician
               And b.BookDate = d.PossibleDate) As SlotsUsed
    FROM    Technicians As t
    CROSS JOIN cteDays d
)
SELECT  PossibleDate, SUM(Util-3) As TotalAvailableSlots
FROM    cteTechnicianUtilization
WHERE   Util < 3
GROUP BY PossibleDate
HAVING  SUM(Util-3) > 0

このアプローチは、再帰を使用するよりも (コード的に) 長い方がはるかに効率的であることに注意してください。

于 2013-06-19T18:56:00.873 に答える