세 개의 관련 테이블이있는 다음 예를 고려하십시오. 주문, 사용자 및 주문 세부 사항. OrderDetails는 외래 키와 함께 Orders 테이블 및 Users 테이블에 연결됩니다. 이것은 본질적으로 관계형 데이터베이스에 대한 매우 일반적인 설정입니다. 아마도 관계형 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);
여기에서는 UserID가 15 인 OrderDetails 테이블을 쿼리합니다.
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
쿼리 출력은 다음과 같습니다.
╔ =======================================
De OrderDetailsID ║ OrderID ║ 사용자 ID ║
╠ =======================================
║ 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 ║
╚ =======================================
보다시피, 행 순서 출력이 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;
╔ =======================================
De OrderDetailsID ║ OrderID ║ 사용자 ID ║
╠ =======================================
║ 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 ║
╚ =======================================
행의 순서가 필수적이며, 당신의 엔지니어 순서가 필수적입니다 알고 있다면, 그들은 오직해야 할 사용하는 ORDER BY
잘못된 순서와 관련된 오류가 있다면 그것은 그들에게 그들의 지정을 비용 수 있으므로, 문을.
다른 테이블을 조인하지 않고 OrderID와 UserID 모두와 일치하는 행을 찾아야하는 간단한 요구 사항이있는 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)
그리고 결과 :
╔ ================== ╗
De OrderDetailsID ║
╠ ================== ╣
421 21421 ║
║ 5061421 ║
║ 7091421 ║
║ 691422 ║
║ 3471422 ║
241 7241422 ║
╚ ================== ╝
ORDER BY
절을 추가하면 여기에서도 올바른 정렬을 얻을 수 있습니다.
이 모형은 행이 명시적인 ORDER BY
진술 없이 "정렬"된 것으로 보장되지 않는 간단한 예일뿐입니다 . 이와 같은 더 많은 예제가 있으며 DBMS 엔진 코드가 자주 변경되므로 특정 동작은 시간이 지남에 따라 변경 될 수 있습니다.