這是我最好的猜測,你想要做什麼。 CTE的前兩部分實際上只是把事情變成一種類似於FlyingStreudel所建議的形式。理想情況下,您應該更改數據庫以匹配該格式,而不是通過CTE執行此操作。這將使這個過程更加簡單,並且對數據完整性也更好。
接下來,我只是以小時爲單位獲得不同的開始時間。如果你不能使用CTE(你沒有提到你使用的SQL Server版本),你可以通過加入數字表來實現。
最後,我使用RAND函數和ROW_NUMBER隨機抓取其中一個開始時間。你會想爲RAND()設置一個好的種子值。
;WITH TimesAsTimes AS
(
SELECT
ScheduleDay,
CAST(SUBSTRING(T1.Time1Start, 1, 2) + ':' + SUBSTRING(T1.Time1Start, 3, 2) AS TIME) AS time_start,
CAST(SUBSTRING(T1.Time1Stop, 1, 2) + ':' + SUBSTRING(T1.Time1Stop, 3, 2) AS TIME) AS time_stop
FROM
tbl1 T1
WHERE
T1.Time1Start IS NOT NULL
UNION ALL
SELECT
ScheduleDay,
CAST(SUBSTRING(T2.Time2Start, 1, 2) + ':' + SUBSTRING(T2.Time2Start, 3, 2) AS TIME) AS time_start,
CAST(SUBSTRING(T2.Time2Stop, 1, 2) + ':' + SUBSTRING(T2.Time2Stop, 3, 2) AS TIME) AS time_stop
FROM
tbl1 T2
WHERE
T2.Time2Start IS NOT NULL
UNION ALL
SELECT
ScheduleDay,
CAST(SUBSTRING(T3.Time3Start, 1, 2) + ':' + SUBSTRING(T3.Time3Start, 3, 2) AS TIME) AS time_start,
CAST(SUBSTRING(T3.Time3Stop, 1, 2) + ':' + SUBSTRING(T3.Time3Stop, 3, 2) AS TIME) AS time_stop
FROM
tbl1 T3
WHERE
T3.Time3Start IS NOT NULL
),
PossibleTimeStarts AS
(
SELECT
ScheduleDay,
time_start,
time_stop
FROM
TimesAsTimes TAT
UNION ALL
SELECT
ScheduleDay,
DATEADD(hh, 1, time_start) AS time_start,
time_stop
FROM
PossibleTimeStarts PTS
WHERE
DATEADD(hh, 1, time_start) <= DATEADD(hh, -1, PTS.time_stop)
),
PossibleTimesWithRowNums AS
(
SELECT
ScheduleDay,
time_start,
ROW_NUMBER() OVER(PARTITION BY ScheduleDay ORDER BY ScheduleDay, time_start) AS row_num,
COUNT(*) OVER(PARTITION BY ScheduleDay) AS num_rows
FROM
PossibleTimeStarts
)
SELECT
*
FROM
PossibleTimesWithRowNums
WHERE
row_num = FLOOR(RAND() * num_rows) + 1
已知哪些輸入?也就是說,ClientId知道查詢何時運行,ScheduleDay是否已知?時間應該只存在於第一對時間還是任何時間對中?它需要如何隨機?也就是說,你有什麼理由不能簡單地在開始時間加一個小時? – Thomas 2010-07-19 14:31:41
而不是給出一個計劃時間的例子,如果你提供了你正在尋找的結果集,那將會更有用。否則,很難幫助你。 – 2010-07-19 14:33:27
Thomas, 查詢運行時ClientID和ScheduleDay是已知的。時間可以來自任何時間,我的要求要求它足夠隨機,以至於無法預測。 Tom H, 查詢的結果將是ClientID,並且該時間屬於提供給查詢的一天中的一對時間。 – DoubleJ92 2010-07-19 14:48:12