ลองพิจารณาตัวอย่างต่อไปนี้โดยที่เรามีสามตารางที่เกี่ยวข้อง คำสั่งซื้อผู้ใช้และรายละเอียดการสั่งซื้อ OrderDetails ถูกเชื่อมโยงกับกุญแจต่างประเทศไปยังตารางคำสั่งซื้อและตารางผู้ใช้ นี่คือการตั้งค่าทั่วไปสำหรับฐานข้อมูลเชิงสัมพันธ์ เนื้อหาวัตถุประสงค์ทั้งหมดของDBMS เชิงสัมพันธ์
USE tempdb;
IF OBJECT_ID(N'dbo.OrderDetails', N'U') IS NOT NULL
DROP TABLE dbo.OrderDetails;
IF OBJECT_ID(N'dbo.Orders', N'U') IS NOT NULL
DROP TABLE dbo.Orders;
IF OBJECT_ID(N'dbo.Users', N'U') IS NOT NULL
DROP TABLE dbo.Users;
CREATE TABLE dbo.Orders
(
OrderID int NOT NULL
CONSTRAINT OrderTestPK
PRIMARY KEY
CLUSTERED
, SomeOrderData varchar(1000)
CONSTRAINT Orders_somedata_df
DEFAULT (CRYPT_GEN_RANDOM(1000))
);
CREATE TABLE dbo.Users
(
UserID int NOT NULL
CONSTRAINT UsersPK
PRIMARY KEY
CLUSTERED
, SomeUserData varchar(1000)
CONSTRAINT Users_somedata_df
DEFAULT (CRYPT_GEN_RANDOM(1000))
);
CREATE TABLE dbo.OrderDetails
(
OrderDetailsID int NOT NULL
CONSTRAINT OrderDetailsTestPK
PRIMARY KEY
CLUSTERED
, OrderID int NOT NULL
CONSTRAINT OrderDetailsOrderID
FOREIGN KEY
REFERENCES dbo.Orders(OrderID)
, UserID int NOT NULL
CONSTRAINT OrderDetailsUserID
FOREIGN KEY
REFERENCES dbo.Users(UserID)
, SomeOrderDetailsData varchar(1000)
CONSTRAINT OrderDetails_somedata_df
DEFAULT (CRYPT_GEN_RANDOM(1000))
);
INSERT INTO dbo.Orders (OrderID)
SELECT TOP(100) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM sys.syscolumns sc;
INSERT INTO dbo.Users (UserID)
SELECT TOP(100) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM sys.syscolumns sc;
INSERT INTO dbo.OrderDetails (OrderDetailsID, OrderID, UserID)
SELECT TOP(10000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
, o.OrderID
, u.UserID
FROM sys.syscolumns sc
CROSS JOIN dbo.Orders o
CROSS JOIN dbo.Users u
ORDER BY NEWID();
CREATE INDEX OrderDetailsOrderID ON dbo.OrderDetails(OrderID);
CREATE INDEX OrderDetailsUserID ON dbo.OrderDetails(UserID);
ที่นี่เรากำลังสอบถามตาราง OrderDetails โดยที่ UserID คือ 15:
SELECT od.OrderDetailsID
, o.OrderID
, u.UserID
FROM dbo.OrderDetails od
INNER JOIN dbo.Users u ON u.UserID = od.UserID
INNER JOIN dbo.Orders o ON od.OrderID = o.OrderID
WHERE u.UserID = 15
ผลลัพธ์จากแบบสอบถามดูเหมือนว่า:
╔════════════════╦═════════╦════════╗
║ OrderDetailsID ║ OrderID ║ UserID ║
╠════════════════╬═════════╬════════╣
00 2200115 ║ 2 ║ 15 ║
║ 630215 ║ 3 ║ 15 ║
║ 1990215 ║ 3 ║ 15 ║
║ 4960215 ║ 3 ║ 15 ║
║ 100715 ║ 8 ║ 15 ║
║ 3930815 ║ 9 ║ 15 ║
║ 6310815 ║ 9 ║ 15 ║
║ 4441015 ║ 11 ║ 15 ║
║ 2171315 ║ 14 ║ 15 ║
║ 3431415 ║ 15 ║ 15 ║
║ 4571415 ║ 15 ║ 15 ║
║ 6421515 ║ 16 ║ 15 ║
║ 2271715 ║ 18 ║ 15 ║
║ 2601715 ║ 18 ║ 15 ║
║ 3521715 ║ 18 ║ 15 ║
18 221815 ║ 19 ║ 15 ║
║ 3381915 ║ 20 ║ 15 ║
║ 4471915 ║ 20 ║ 15 ║
╚════════════════╩═════════╩════════╝
อย่างที่คุณเห็นลำดับของเอาท์พุทแถวไม่ตรงกับลำดับของแถวในตาราง OrderDetails
การเพิ่มORDER BY
แถวชัดเจนจะส่งกลับไปยังลูกค้าตามลำดับที่ต้องการ:
SELECT od.OrderDetailsID
, o.OrderID
, u.UserID
FROM dbo.OrderDetails od
INNER JOIN dbo.Users u ON u.UserID = od.UserID
INNER JOIN dbo.Orders o ON od.OrderID = o.OrderID
WHERE u.UserID = 15
ORDER BY od.OrderDetailsID;
╔════════════════╦═════════╦════════╗
║ OrderDetailsID ║ OrderID ║ UserID ║
╠════════════════╬═════════╬════════╣
║ 3915 ║ 40 ║ 15 ║
║ 100715 ║ 8 ║ 15 ║
18 221815 ║ 19 ║ 15 ║
║ 299915 ║ 100 ║ 15 ║
║ 368215 ║ 83 ║ 15 ║
║ 603815 ║ 39 ║ 15 ║
║ 630215 ║ 3 ║ 15 ║
║ 728515 ║ 86 ║ 15 ║
║ 972215 ║ 23 ║ 15 ║
║ 992015 ║ 21 ║ 15 ║
║ 1017115 ║ 72 ║ 15 ║
║ 1113815 ║ 39 ║ 15 ║
╚════════════════╩═════════╩════════╝
หากคำสั่งของแถวมีความจำเป็นและวิศวกรของคุณรู้ว่าคำสั่งนั้นมีความจำเป็นพวกเขาควรจะต้องการใช้ORDER BY
คำสั่งเพียงอย่างเดียวเนื่องจากอาจทำให้พวกเขาต้องเสียค่าใช้จ่ายหากพวกเขามีข้อผิดพลาดที่เกี่ยวข้องกับคำสั่งที่ไม่ถูกต้อง
ตัวอย่างที่สองอาจเป็นคำแนะนำเพิ่มเติมโดยใช้OrderDetails
ตารางจากด้านบนซึ่งเราไม่ได้เข้าร่วมตารางอื่น ๆ แต่มีข้อกำหนดง่าย ๆ ในการค้นหาแถวที่ตรงกับทั้งรหัสผู้ใช้และรหัสผู้ใช้เราเห็นปัญหา
เราจะสร้างดัชนีเพื่อสนับสนุนการสืบค้นตามที่คุณน่าจะทำในชีวิตจริงหากประสิทธิภาพนั้นสำคัญไม่ว่าจะเป็นอย่างไร
CREATE INDEX OrderDetailsOrderIDUserID ON dbo.OrderDetails(OrderID, UserID);
นี่คือแบบสอบถาม:
SELECT od.OrderDetailsID
FROM dbo.OrderDetails od
WHERE od.OrderID = 15
AND (od.UserID = 21 OR od.UserID = 22)
และผลลัพธ์:
╔════════════════╗
║ OrderDetailsID ║
╠════════════════╣
║ 21421 ║
║ 5061421 ║
║ 7091421 ║
║ 691422 ║
║ 3471422 ║
║ 7241422 ║
╚════════════════╝
การเพิ่มส่วนORDER BY
คำสั่งจะช่วยให้แน่ใจว่าเราจะได้รับการจัดเรียงที่ถูกต้องที่นี่เช่นกัน
ตัวอย่างเหล่านี้เป็นเพียงตัวอย่างง่ายๆที่ไม่รับประกันว่าแถวจะ "อยู่ในลำดับ" โดยไม่มีORDER BY
คำสั่งที่ชัดเจน มีตัวอย่างอีกมากมายเช่นนี้และเนื่องจากรหัสเครื่องยนต์ DBMS มีการเปลี่ยนแปลงค่อนข้างบ่อยลักษณะการทำงานที่เฉพาะเจาะจงอาจเปลี่ยนแปลงตลอดเวลา