Tôi có một bảng có giao dịch cho xe buýt (người đi lên máy bay). Đưa ra ID tuyến đường và ngày , tôi cần tra cứu trong một bảng khác loại dịch vụ mà nó đã làm ngày hôm đó. Lịch trình xe buýt thay đổi nhiều nhất cứ sau 6 tháng hoặc lâu hơn, với hầu hết các năm sẽ không thay đổi.
Hiện tại bảng lịch trình được định nghĩa như vậy:
CREATE TABLE [dbo].[Routes](
[ID] [int] NOT NULL,
[RouteID] [int] NOT NULL,
[Type] [varchar](50) NOT NULL,
[StartDate] [datetime] NOT NULL,
PRIMARY KEY CLUSTERED
(
[ID] ASC
));
Một ví dụ có thể trông giống như:
ID RouteID Type StartDate
-- ------- ------------ ----------
1 301 Standard 2015-01-01
2 301 Discontinued 2016-06-01
3 302 Standard 2015-01-01
4 302 ParaTrans 2017-01-01
Vì vậy, nếu tôi có giao dịch từ 2015-04-20 cho RouteID
301 , tôi muốn lấy lại "Tiêu chuẩn", nhưng nếu giao dịch là từ 2018-01-20 , thì nó sẽ trả về "Ngưng". Đối với các giao dịch trước 2015-01-01 , nó sẽ trả về NULL (hoặc "" hoặc bất kỳ điều gì khác ngoài kết quả có thể mâu thuẫn với câu trả lời hợp lệ, ví dụ: "Tiêu chuẩn", "Paratrans" hoặc "Ngưng").
Về cơ bản, bảng biểu thị rằng tuyến 301 là tuyến tiêu chuẩn trong khoảng thời gian 2015-01-01 và 2016-05-31 (và do đó, bất kỳ giao dịch nào trong khoảng thời gian đó nên được phân loại là "Tiêu chuẩn"), sau đó nó đã bị ngừng vào ngày 2016-06- 01 (cho đến ngày hiện tại, mặc nhiên không có thay đổi lịch trình nào được ghi nhận), trong khi 302 là tuyến Tiêu chuẩn từ 2015-01-01 đến 2016-12-31 , sau đó là tuyến ParaTrans (nó) sau đó.
Route Type Start End
----- ---- ----- ---
301
Standard 2015-01-01 2016-05-31
Discontinued 2016-06-01 Present
302
Standard 2015-01-01 2016-12-31
ParaTrans 2017-01-01 Present
Hiện tại, truy vấn để làm điều này trông như thế này:
SELECT
TRANSIT_DAY,
ROUTE_ID,
(SELECT TOP (1) Type FROM Routes
WHERE (RouteID = dbo.DAILY_SALES_DETAIL.ROUTE_ID)
AND (StartDate <= dbo.DAILY_SALES_DETAIL.TRANSIT_DAY)
ORDER BY StartDate DESC) AS NCTD_MODE
FROM dbo.DAILY_SALES_DETAIL
Câu hỏi
Điều tôi muốn biết là: Đây có phải là sự kết hợp hiệu quả nhất của (a) cấu trúc của Routes
bảng và (b) truy vấn để đạt được kết quả này không? Nói cách khác, một truy vấn hiệu quả hơn có thể được sử dụng với cấu trúc hiện có không? Có thể thay đổi bảng tuyến đường cho phép truy vấn hiệu quả hơn không?
Cân nhắc
Bảng giao dịch được nhập từ một nhà cung cấp hàng ngày và do đó, việc thay đổi lược đồ của bảng đó không phải là chuyện nhỏ và nên tránh sử dụng. Quan trọng hơn, việc tra cứu này được sử dụng trên một số bảng và cơ sở dữ liệu bằng cách sử dụng các giao dịch hoặc dữ liệu liên quan đến xe buýt khác có nguồn gốc từ nhiều nhà cung cấp; đây chỉ là một ví dụ duy nhất Chúng tôi có một nhà cung cấp (và do đó là một cơ sở dữ liệu) cho các giao dịch tiền tệ, một nhà cung cấp khác cho số người lái và vẫn là một nhà cung cấp khác cho hiệu suất, v.v., với số tuyến và ngày là định danh duy nhất đáng tin cậy trên tất cả.
Bảng lộ trình có một chỉ số là (RouteID, StartDate)
. Hiện tại có 56 hàng trong bảng Tuyến và 26 triệu hàng trong bảng giao dịch. Bảng tuyến đường bao gồm 45 tuyến đường và hiện tại không có tuyến đường nào có nhiều hơn 2 hàng hoặc một thay đổi. Không có giới hạn về số lượng thay đổi mà một tuyến đường có thể có, nhưng tôi bao gồm chỉ số này để cho thấy rằng con số có thể vẫn còn nhỏ trong tương lai gần.
Tôi có thể thêm bất kỳ chỉ mục cần thiết nào để tối ưu hóa truy vấn được đề xuất. Câu hỏi liên quan nhiều hơn đến việc tìm ra chiến lược tốt nhất, giả sử tất cả các tối ưu hóa hợp lý được thực hiện cho các chiến lược được xem xét, hơn là tìm kiếm tối ưu hóa tốt nhất cho một chiến lược cụ thể.
db <> fiddle ở đây