我目前正在開發一個學校的數據庫系統,該系統將與我們的預訂系統一起工作,以便學生可以預訂他們的課程,並且我們可以更好地跟蹤他們的活動。現在我面臨一個複雜的問題,我想要做的是檢查哪些學生合同是有效的,我可以通過使用下面的函數來實現,但我想看看是否有更簡單的方法來正確執行它(除此之外存儲我可以在系統中計算的數據。)複雜的SQL語句的可行性
如果合同有效,那麼學生沒有用完他們購買的所有小時數,購買的小時數是他們參加的教學班長度加上他們錯過但預定了每班的長度總和(在某個數字之後,例如3或5)。我可以用下面的查詢做,但我覺得必須有一個簡單的方法:
SELECT
level.name
FROM
(
SELECT
contract.level_package_id,
contract_class_hours.hours_purchased,
(
SELECT
isnull(sum(DATEPART(hh, class.end_date - class.start_date)), 0)
FROM
booking
JOIN class ON class.id = booking.class_id
WHERE
booking.booking_state_id = 3
AND booking.contract_id = contract.id
) AS time_attended,
(
SELECT
isnull(sum(absent_class_lengths.length), 0)
FROM
(
SELECT
DATEPART(hh, class.end_date - class.start_date) AS length,
row_number() OVER (ORDER BY class.start_date) AS rn
FROM
booking
JOIN class ON class.id = booking.class_id
WHERE
student_id = 5
AND booking_state_id = 4
AND booking.contract_id = contract.id
) absent_class_lengths
WHERE
rn > contract_class_hours.absences_allowed
) as time_absent
FROM
contract
JOIN contract_class_hours ON contract_class_hours.contract_id = contract.id
) test
JOIN level_package_level ON level_package_level.level_package_id = test.level_package_id
JOIN level ON level.id = level_package_level.level_id
WHERE
test.time_absent + test.time_attended < test.hours_purchased
AND level.study_type_id = 2
- booking.state_id = 3表示該學生上課
- booking.state_id = 4表示該學生是缺席
- level.study_type_id = 2僅僅是一個過程主體
表包含這樣的數據列(忽略level_id,它僅僅是我需要返回值):
CLASS
id - int
end_date - datetime
start_date - datetime
BOOKING
id - int
class_id - int
student_id - int
booking_state_id - smallint
BOOKING_STATE
id - int
state - varchar(20) [absent, attended]
CONTRACT
id - int
student_id - int
level_id - int
hours_purchased - smallint
absenses_allowed - smallint
STUDENT
id - int
我意識到這可能是複雜的問題要問,但我只是想知道,如果這真的是做事的正確方法,或者我應該節省一些排序字段中有合約表幾個小時出席並假定它總是準確的。
對一些表格定義會很好 - 我覺得我們在這裏重新建模? – Mike
如果爲表格添加測試數據,並且參數的預期輸出更容易重寫。 –
我可以提供一些定義,但我想知道這是否是解決問題的好方法。在我們所有的合同到期之前,我只需要檢查結束日期。但是現在他們可以有幾種不同的口味,最重要的是幾個小時。此外,該功能正在運行完美,我只是覺得我可以讓事情變得更簡單。 –