我有以下查询,我需要修改它,以便originDocForCurrency.id = 68
如果没有匹配的commission.referenzid = 68
. 我尝试了RIGHT OUTER JOIN
ON commission.referenzid = originDocForCurrency.id
,但它不会给出结果,如果没有找到commission.referenzid = 68
.
SELECT
commission.netto AS commissionNetValue,
commission.r_art AS commissionDocClass,
commission.waehrung AS commissionCurrency,
currencies.usd_brief AS foreignCurrencyUSDAsk,
currencies.usd_geld AS foreignCurrencyUSDBid,
originDocForCurrency.r_art AS originDocForCurrencyDocClass,
originDocForCurrency.poswert AS originDocForCurrencyCommission,
(SELECT originDoc.poswert FROM [src_boss_entwicklung].[dbo].[tckopf] AS originDoc WHERE originDoc.id = 68) AS originDocCommission,
(SELECT originDoc.r_art FROM [src_boss_entwicklung].[dbo].[tckopf] AS originDoc WHERE originDoc.id = 68) AS originDocClass,
(SELECT originDoc.waehrung FROM [src_boss_entwicklung].[dbo].[tckopf] AS originDoc WHERE originDoc.id = 68) AS originDocCurrency
FROM
[src_boss_entwicklung].[dbo].[tckopf] AS commission
RIGHT OUTER JOIN
[src_boss_entwicklung].[dbo].[tckopf] AS originDocForCurrency
ON commission.referenzid = originDocForCurrency.id
LEFT OUTER JOIN
[src_boss_entwicklung].[dbo].[devisen] AS currencies
ON currencies.datum = (
SELECT TOP 1 fc.datum
FROM [src_boss_entwicklung].[dbo].[devisen] AS fc
WHERE fc.datum <= originDocForCurrency.von
AND fc.usd_brief IS NOT NULL AND fc.usd_brief > 0
AND fc.usd_geld IS NOT NULL AND fc.usd_geld > 0
ORDER BY fc.datum DESC
)
WHERE
originDocForCurrency.id = 68
AND
( commission.referenzid = 68
AND commission.btyp = 7
AND ( commission.storno <> 1 OR commission.storno IS NULL )
AND ( commission.proforma <> 1 OR commission.proforma IS NULL ) )
OR
( commission.referenzid = 68
AND commission.btyp = 8
AND ( commission.storno <> 1 OR commission.storno IS NULL )
AND ( commission.proforma <> 1 OR commission.proforma IS NULL ) )
Run Code Online (Sandbox Code Playgroud)
如何修改查询以获得所需的结果?我可以CASE
在WHERE
子句中使用 a 达到预期的结果吗?
为了稍微简化您的查询,您基本上有以下内容:
SELECT *
FROM
[src_boss_entwicklung].[dbo].[tckopf] AS commission
RIGHT OUTER JOIN
[src_boss_entwicklung].[dbo].[tckopf] AS originDocForCurrency
ON commission.referenzid = originDocForCurrency.id
WHERE
originDocForCurrency.id = 68
AND (commission.referenzid = 68 OR commission.referenzid = 68);
Run Code Online (Sandbox Code Playgroud)
[src_boss_entwicklung].[dbo].[tckopf]
列中没有匹配项的地方commission.referenzid
将为 NULL,这意味着此条件:
AND (commission.referenzid = 68 OR commission.referenzid = 68);
Run Code Online (Sandbox Code Playgroud)
这些行不会为真(因为NULL = 68
计算结果为NULL
)。这有效地使您RIGHT OUTER JOIN
的INNER JOIN
我从来都不是超级粉丝,RIGHT JOIN
尤其是LEFT JOIN
出现在同一个查询中时。为了连续性,我会重新排列查询以使所有外部连接都离开外部连接:
SELECT *
FROM
[src_boss_entwicklung].[dbo].[tckopf] AS originDocForCurrency
LEFT OUTER JOIN
[src_boss_entwicklung].[dbo].[tckopf] AS commission
ON commission.referenzid = originDocForCurrency.id
LEFT OUTER JOIN
[src_boss_entwicklung].[dbo].[devisen] AS currencies
ON currencies.datum = (
SELECT TOP 1 fc.datum
FROM [src_boss_entwicklung].[dbo].[devisen] AS fc
WHERE fc.datum <= originDocForCurrency.von
AND fc.usd_brief IS NOT NULL AND fc.usd_brief > 0
AND fc.usd_geld IS NOT NULL AND fc.usd_geld > 0
ORDER BY fc.datum DESC
)
WHERE
originDocForCurrency.id = 68
AND (commission.referenzid = 68 OR commission.referenzid = 68);
Run Code Online (Sandbox Code Playgroud)
但因为你仍然有可能这不会解决问题commission.referenzid
是NULL
并打开左外连接到内连接。您可以通过将谓词移动到 JOIN 条件来解决这个问题:
SELECT *
FROM
[src_boss_entwicklung].[dbo].[tckopf] AS originDocForCurrency
LEFT OUTER JOIN
[src_boss_entwicklung].[dbo].[tckopf] AS commission
ON commission.referenzid = originDocForCurrency.id
AND
( commission.referenzid = 68
AND commission.btyp = 7
AND ( commission.storno <> 1 OR commission.storno IS NULL )
AND ( commission.proforma <> 1 OR commission.proforma IS NULL ) )
OR
( commission.referenzid = 68
AND commission.btyp = 8
AND ( commission.storno <> 1 OR commission.storno IS NULL )
AND ( commission.proforma <> 1 OR commission.proforma IS NULL )
)
Run Code Online (Sandbox Code Playgroud)
我也相当肯定这个条件可以简化为:
SELECT *
FROM
[src_boss_entwicklung].[dbo].[tckopf] AS originDocForCurrency
LEFT OUTER JOIN
[src_boss_entwicklung].[dbo].[tckopf] AS commission
ON commission.referenzid = originDocForCurrency.id
AND commission.referenzid = 68
AND commission.btyp in (7, 8)
AND ISNULL(commission.storno, 0) <> 1
AND ISNULL(commission.proforma, 0) <> 1
Run Code Online (Sandbox Code Playgroud)
进行您的最终查询:
SELECT
commission.netto AS commissionNetValue,
commission.r_art AS commissionDocClass,
commission.waehrung AS commissionCurrency,
currencies.usd_brief AS foreignCurrencyUSDAsk,
currencies.usd_geld AS foreignCurrencyUSDBid,
originDocForCurrency.r_art AS originDocForCurrencyDocClass,
originDocForCurrency.poswert AS originDocForCurrencyCommission,
(SELECT originDoc.poswert FROM [src_boss_entwicklung].[dbo].[tckopf] AS originDoc WHERE originDoc.id = 68) AS originDocCommission,
(SELECT originDoc.r_art FROM [src_boss_entwicklung].[dbo].[tckopf] AS originDoc WHERE originDoc.id = 68) AS originDocClass,
(SELECT originDoc.waehrung FROM [src_boss_entwicklung].[dbo].[tckopf] AS originDoc WHERE originDoc.id = 68) AS originDocCurrency
FROM
[src_boss_entwicklung].[dbo].[tckopf] AS originDocForCurrency
LEFT OUTER JOIN
[src_boss_entwicklung].[dbo].[tckopf] AS commission
ON commission.referenzid = originDocForCurrency.id
AND commission.referenzid = 68
AND commission.btyp in (7, 8)
AND ISNULL(commission.storno, 0) <> 1
AND ISNULL(commission.proforma, 0) <> 1
LEFT OUTER JOIN
[src_boss_entwicklung].[dbo].[devisen] AS currencies
ON currencies.datum = (
SELECT TOP 1 fc.datum
FROM [src_boss_entwicklung].[dbo].[devisen] AS fc
WHERE fc.datum <= originDocForCurrency.von
AND fc.usd_brief IS NOT NULL AND fc.usd_brief > 0
AND fc.usd_geld IS NOT NULL AND fc.usd_geld > 0
ORDER BY fc.datum DESC
)
WHERE
originDocForCurrency.id = 68;
Run Code Online (Sandbox Code Playgroud)
附录
正如评论中指出的那样,您不需要三个子选择,您可以只使用表中的列 aliased originDocForCurrency
:
SELECT
commission.netto AS commissionNetValue,
commission.r_art AS commissionDocClass,
commission.waehrung AS commissionCurrency,
currencies.usd_brief AS foreignCurrencyUSDAsk,
currencies.usd_geld AS foreignCurrencyUSDBid,
originDocForCurrency.r_art AS originDocForCurrencyDocClass,
originDocForCurrency.poswert AS originDocForCurrencyCommission,
originDocForCurrency.poswert AS originDocCommission,
originDocForCurrency.r_art AS originDocClass,
originDocForCurrency.waehrung AS originDocCurrency
FROM
[src_boss_entwicklung].[dbo].[tckopf] AS originDocForCurrency
LEFT OUTER JOIN
[src_boss_entwicklung].[dbo].[tckopf] AS commission
ON commission.referenzid = originDocForCurrency.id
AND commission.btyp in (7, 8)
AND ISNULL(commission.storno, 0) <> 1
AND ISNULL(commission.proforma, 0) <> 1
LEFT OUTER JOIN
[src_boss_entwicklung].[dbo].[devisen] AS currencies
ON currencies.datum = (
SELECT TOP 1 fc.datum
FROM [src_boss_entwicklung].[dbo].[devisen] AS fc
WHERE fc.datum <= originDocForCurrency.von
AND fc.usd_brief IS NOT NULL AND fc.usd_brief > 0
AND fc.usd_geld IS NOT NULL AND fc.usd_geld > 0
ORDER BY fc.datum DESC
)
WHERE
originDocForCurrency.id = 68;
Run Code Online (Sandbox Code Playgroud)