要求是在某些欄位上連接(配對)兩個表,然后按順序顯示配對結果。在 CTE 中進行配對。一對被分配一個 GUID,然后用于按順序顯示每一對。它對 Oracle(11.2)按預期作業,但對于 SQL Server(2017),似乎 CTE 被創建了兩次,因為每一行都有自己的 GUID。
我如何使用 CTE 解決它?為什么 SQL Server 會這樣?
SQL Server http://sqlfiddle.com/#!18/21c167/1
Oracle http://sqlfiddle.com/#!4/c49dbb/2 (已使用 DBMS_RANDOM.RANDOM 而不是 SYS_GUID() 因為 SYS_GUID() 在我的開發機器上正常作業時為 sqlfiddle.com 上的所有行回傳相同的值)
CREATE TABLE VEHICLE (CODE NUMERIC(3,0), [TYPE] VARCHAR(50), DRIVER_CATEGORY VARCHAR(2));
CREATE TABLE DRIVER (CODE NUMERIC(9,0), NAME VARCHAR(200), CATEGORY VARCHAR(2));
INSERT INTO VEHICLE VALUES (1, 'LIMOUSINE', 'A');
INSERT INTO VEHICLE VALUES (2, 'TRUCK', 'B');
INSERT INTO VEHICLE VALUES (3, 'SUV', 'C');
INSERT INTO VEHICLE VALUES (4, 'SEDAN', 'C');
INSERT INTO VEHICLE VALUES (5, 'SPORTS CAR', 'D');
INSERT INTO DRIVER VALUES (1, 'James', 'A');
INSERT INTO DRIVER VALUES (2, 'Robert', 'B');
INSERT INTO DRIVER VALUES (3, 'John', 'C');
INSERT INTO DRIVER VALUES (4, 'Jennifer', 'C');
INSERT INTO DRIVER VALUES (5, 'Patricia', 'D');
INSERT INTO DRIVER VALUES (6, 'Susan', 'A');
INSERT INTO DRIVER VALUES (7, 'Lisa', 'B');
;WITH MATCHPAIRS AS
(
SELECT V.CODE VEHICLE_CODE, D.CODE DRIVER_CODE, V.TYPE TYPE, V.DRIVER_CATEGORY, D.NAME, D.CATEGORY, NewID() PAIRID
FROM VEHICLE V INNER JOIN DRIVER D ON V.DRIVER_CATEGORY = D.CATEGORY
)
SELECT p.VEHICLE_CODE, p.DRIVER_CODE, P.PAIRID, V.TYPE TYPE_NAME, 0 RECORD_ORDER
FROM VEHICLE V INNER JOIN MATCHPAIRS P ON V.CODE = P.VEHICLE_CODE
UNION ALL
SELECT p.VEHICLE_CODE, p.DRIVER_CODE, P.PAIRID, D.NAME TYPE_NAME, 1 RECORD_ORDER
FROM DRIVER D INNER JOIN MATCHPAIRS P ON D.CODE = P.DRIVER_CODE
ORDER BY PAIRID, RECORD_ORDER
uj5u.com熱心網友回復:
CTE 不會被快取,它們會針對每個參考重新計算。
無論如何,NEWID有時會做一些奇怪的事情,當不在最外層使用時SELECT,最好使用臨時表。CROSS APPLY或者CROSS JOIN有時也不會與NEWID.
或者,改用不同的唯一性。例如
;WITH MATCHPAIRS AS (
SELECT
V.CODE VEHICLE_CODE,
D.CODE DRIVER_CODE,
V.TYPE TYPE,
V.DRIVER_CATEGORY,
D.NAME,
D.CATEGORY,
ROW_NUMBER() OVER (ORDER BY v.CODE, D.CODE) PAIRID
FROM VEHICLE V
INNER JOIN DRIVER D ON V.DRIVER_CATEGORY = D.CATEGORY
)
SELECT
p.VEHICLE_CODE,
p.DRIVER_CODE,
P.PAIRID,
V1.TYPE_NAME,
v1.RECORD_ORDER
FROM MATCHPAIRS P
CROSS APPLY (VALUES
(p.TYPE, 0),
(p.NAME, 1)
) V1(TYPE_NAME, RECORD_ORDER)
ORDER BY
PAIRID,
RECORD_ORDER;
注意CROSS APPLY (VALUESto unpivot 的使用,這樣可以節省兩次讀取 CTE。
SQL小提琴
uj5u.com熱心網友回復:
最簡單的解決方案是使用臨時表而不是 CTE。如果需要,您可以將代碼包裝在存盤程序中。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/510537.html
下一篇:更新列中的日期字串
