我想知道在下面的例子中是否有更好的方法来创建我的左连接
SELECT TOP 10 COALESCE(A.COD_PRODUCT, B.COD_PRODUCT),
COALESCE(A.COD_FAMILY, B.COD_FAMILY),
COALESCE(A.DATE_EXTRACT, B.DATE_EXTRACT),
A.MASS
B.VOLUME
C.PRICE
FROM FIRSTTABLE A
FULL JOIN SECONDTABLE B
ON B.COD_PRODUCT = A.COD_PRODUCT
AND B.COD_FAMILY = A.COD_FAMILY
AND B.DATE_EXTRACT = A.DATE_EXTRACT
LEFT JOIN THIRDTABLE C
ON C.COD_PRODUCT = COALESCE(A.COD_PRODUCT, B.COD_PRODUCT)
AND C.COD_FAMILY = COALESCE(A.COD_FAMILY, B.COD_FAMILY)
AND C.DATE_EXTRACT = COALESCE(A.DATE_EXTRACT, B.DATE_EXTRACT)
这种关节需要很长时间,我怀疑它非常昂贵且可以改进
编辑:我想在视图中改进此SELECt FROM JOIN语句。
答案 0 :(得分:0)
将执行计划与此替换联接进行比较:
LEFT JOIN THIRDTABLE C
ON (C.COD_PRODUCT = A.COD_PRODUCT or C.COD_PRODUCT = B.COD_PRODUCT)
AND (C.COD_FAMILY = A.COD_FAMILY or C.COD_FAMILY = B.COD_FAMILY)
AND (C.DATE_EXTRACT =A.DATE_EXTRACT or C.DATE_EXTRACT = B.DATE_EXTRACT)
答案 1 :(得分:0)
您可以使用UNION或UNION ALL
获得相同的结果WITH cte AS (
SELECT
A.COD_PRODUCT,
A.COD_FAMILY,
A.DATE_EXTRACT,
A.MASS,
NULL as VOLUME
FROM
FIRSTTABLE A
UNION
SELECT
B.COD_PRODUCT,
B.COD_FAMILY,
B.DATE_EXTRACT,
NULL,
B.VOLUME
FROM
FIRSTTABLE A
)
SELECT
*
FROM
cte AB
LEFT JOIN
THIRDTABLE C ON C.COD_PRODUCT = AB.COD_PRODUCT
AND C.COD_FAMILY = AB.COD_FAMILY
AND C.DATE_EXTRACT = AB.DATE_EXTRACT
如果您可以为产品,系列,提取组合提供质量和体积,则可以使用聚合来一起加入A和B
WITH cte AS (
SELECT
COD_PRODUCT,
COD_FAMILY,
DATE_EXTRACT,
MAX(MASS) MASS,
MAX(VOLUME) VOLUME
FROM (
SELECT
A.COD_PRODUCT,
A.COD_FAMILY,
A.DATE_EXTRACT,
A.MASS,
NULL as VOLUME
FROM
FIRSTTABLE A
UNION ALL
SELECT
B.COD_PRODUCT,
B.COD_FAMILY,
B.DATE_EXTRACT,
NULL,
B.VOLUME
FROM
FIRSTTABLE A
) T
GROUP BY
COD_PRODUCT,
COD_FAMILY,
DATE_EXTRACT
)
SELECT
*
FROM
cte AB
LEFT JOIN
THIRDTABLE C ON C.COD_PRODUCT = AB.COD_PRODUCT
AND C.COD_FAMILY = AB.COD_FAMILY
AND C.DATE_EXTRACT = AB.DATE_EXTRACT
答案 2 :(得分:0)
你可以试试这个:
--- isolate the full join data from a and b into a temp table
SELECT
COD_PRODUCT= COALESCE(A.COD_PRODUCT, B.COD_PRODUCT),
COD_FAMILY= COALESCE(A.COD_FAMILY, B.COD_FAMILY),
DATE_EXTRACT= COALESCE(A.DATE_EXTRACT, B.DATE_EXTRACT),
MASS= A.MASS,
VOLUME= B.VOLUME
INTO #TEMP
FROM FIRSTTABLE A
FULL JOIN SECONDTABLE B
ON B.COD_PRODUCT = A.COD_PRODUCT
AND B.COD_FAMILY = A.COD_FAMILY
AND B.DATE_EXTRACT = A.DATE_EXTRACT
-- add index clustered onto table (covering index)
CREATE CLUSTERED INDEX ix_tempCIndex ON #Temp ([COD_PRODUCT],[COD_FAMILY],[DATE_EXTRACT],[MASS],[VOLUME]);
-- left join C to this temp table
SELECT TOP 10
T.*, C.PRICE
FROM #TEMP T
LEFT JOIN THIRDTABLE C
ON C.COD_PRODUCT = T.COD_PRODUCT
AND C.COD_FAMILY = T.COD_FAMILY
AND C.DATE_EXTRACT = T.DATE_EXTRACT
-- drop temp table
DROP TABLE #TEMP
答案 3 :(得分:0)
您可以将查询分为两部分:收集所有与FIRSTTABLE匹配的数据。然后将其与FIRSTTABLE中没有的所有匹配SECONDTABLE的数据合并。
这应该使SQL Server可以更好地使用这些表上的索引。
SELECT A.COD_PRODUCT,
A.COD_FAMILY,
A.DATE_EXTRACT,
A.MASS,
B.VOLUME,
C.PRICE
FROM FIRSTTABLE A
LEFT OUTER JOIN SECONDTABLE B
ON B.COD_PRODUCT = A.COD_PRODUCT
AND B.COD_FAMILY = A.COD_FAMILY
AND B.DATE_EXTRACT = A.DATE_EXTRACT
LEFT OUTER JOIN THIRDTABLE C
ON C.COD_PRODUCT = A.COD_PRODUCT
AND C.COD_FAMILY = A.COD_FAMILY
AND C.DATE_EXTRACT = A.DATE_EXTRACT
UNION ALL
SELECT B.COD_PRODUCT,
B.COD_FAMILY,
B.DATE_EXTRACT,
NULL AS MASS,
B.VOLUME,
C.PRICE
FROM SECONDTABLE B
LEFT OUTER JOIN THIRDTABLE C
ON C.COD_PRODUCT = B.COD_PRODUCT
AND C.COD_FAMILY = B.COD_FAMILY
AND C.DATE_EXTRACT = B.DATE_EXTRACT
WHERE NOT EXISTS (SELECT 1
FROM FIRSTTABLE A
WHERE A.COD_PRODUCT = B.COD_PRODUCT
AND A.COD_FAMILY = B.COD_FAMILY
AND A.DATE_EXTRACT = B.DATE_EXTRACT)
答案 4 :(得分:0)
联接内的合并或OR将大大减慢查询速度。根据表的大小,更好的答案可能是两次连接到表c。一次在表a上,再一次在表B上,然后在select子句内部合并。
选择前10大凉粉(A.COD_PRODUCT,B.COD_PRODUCT,c.COD_PRODUCT,ca.COD_PRODUCT),
COALESCE(A.COD_FAMILY,B.COD_FAMILY,c.COD_FAMILY,ca.COD_FAMILY),
COALESCE(A.DATE_EXTRACT,B.DATE_EXTRACT,c.DATE_EXTRACT,ca.DATE_EXTRACT),
A.MASS
B.VOLUME
C.PRICE
来自第一表A
完全联接第二台B
ON B.COD_PRODUCT = A.COD_PRODUCT
AND B.COD_FAMILY = A.COD_FAMILY
AND B.DATE_EXTRACT = A.DATE_EXTRACT
左联接第三台C
ON C.COD_PRODUCT = A.COD_PRODUCT
AND C.COD_FAMILY = A.COD_FAMILY
AND C.DATE_EXTRACT = A.DATE_EXTRACT
左联接三级钙
开启Ca.COD_PRODUCT = b.COD_PRODUCT
AND Ca.COD_FAMILY = b.COD_FAMILY
AND Ca.DATE_EXTRACT = b.DATE_EXTRACT