İlişkili üç tablomuz olan aşağıdaki örneği düşünün. Siparişler, Kullanıcılar ve OrderDetails. OrderDetails, yabancı anahtarlarla Siparişler tablosuna ve Kullanıcı Tablosuna bağlanır. Bu aslında ilişkisel veritabanları için çok tipik bir kurulumdur; tartışmalı bir ilişkisel DBMS'nin tüm amacı .
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);
Burada, Kullanıcı Adının 15 olduğu OrderDetails tablosunu sorguluyoruz:
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
Sorgudan çıkan çıktı şöyle görünür:
╔════════════════╦═════════╦════════╗
De OrderDetailsID ║ OrderID ║ Kullanıcı Kimliği ║
╠════════════════╬═════════╬════════╣
║ 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 ║
║ 221815 ║ 19 ║ 15 ║
║ 3381915 ║ 20 ║ 15 ║
║ 4471915 ║ 20 ║ 15 ║
╚════════════════╩═════════╩════════╝
Gördüğünüz gibi, satır çıktısının sırası, OrderDetails tablosundaki satırların sırasına uymuyor.
Açık bir şekilde eklemek, ORDER BY
satırların müşteriye istenen sırada geri gönderilmesini sağlar:
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;
╔════════════════╦═════════╦════════╗
De OrderDetailsID ║ OrderID ║ Kullanıcı Kimliği ║
╠════════════════╬═════════╬════════╣
║ 3915 ║ 40 ║ 15 ║
║ 100715 ║ 8 ║ 15 ║
║ 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 ║
╚════════════════╩═════════╩════════╝
Satırların sırası zorunludur, ve mühendisler bu düzen şarttır bilirlerse, sadece hiç gerektiğini istediğiniz bir kullanmak ORDER BY
yanlış sipariş ile ilgili bir başarısızlık varsa o onlara atamasını mal olabilir çünkü deyimi.
Bir kullanarak ikinci, belki de daha öğretici bir örnek, OrderDetails
biz nereye yukarıdan tablo değil başka tablo birleştirme, ancak Sipariş Kimliği ve kullanıcı kimliği hem eşleşen satırları bulmak için basit bir şartı var, biz sorun görüyoruz.
Performansı herhangi bir şekilde önemliyse, gerçek hayatta muhtemelen yapacağınız gibi, sorguyu desteklemek için bir dizin oluşturacağız (ne zaman değil?).
CREATE INDEX OrderDetailsOrderIDUserID ON dbo.OrderDetails(OrderID, UserID);
İşte sorgu:
SELECT od.OrderDetailsID
FROM dbo.OrderDetails od
WHERE od.OrderID = 15
AND (od.UserID = 21 OR od.UserID = 22)
Ve sonuçlar:
╔════════════════╗
De OrderDetailsID ║
╠════════════════╣
║ 21421 ║
║ 5061421 ║
║ 7091421 ║
14 691422 ║
3471422
║ 7241422 ║
╚════════════════╝
Bir ORDER BY
cümle eklemek kesinlikle burada doğru sıralamayı almamızı sağlayacaktır.
Bu örnekler, açık bir ORDER BY
ifade olmadan satırların "sıralı" olmalarının garanti edilmediği basit örneklerdir . Bunun gibi daha pek çok örnek var ve DBMS motor kodu oldukça sık değiştiğinden, belirli davranış zaman içinde değişebilir.