查询联接空值(左外部联接)

任何。05

继续对帖子提出的要求:

Ora SQL查询:没有引用的联接

现在我有以下情况:

想法是通过TABLE_A中的输入从TABLE_M中获得组合。

例如。TABLE_A中的记录1(CODE = 1)分别对应于TABLE_Z和TABLE_X时对应于COMBINATION1 ...

问题出在2、3或4之类的组合中(TABLE_A中的CODE)。这些组合在TABLE_Z和TABLE_X中没有任何匹配值,因此最终结果应类似于:

  • TABLE_A(code2)---->组合7
  • TABLE_A(code3)---->组合9
  • TABLE_A(code4)---->组合8

我试图通过使用OUTER JOINS来实现此目的,但无法成功获取它... :(

SELECT A.REF_X,A.REF_Z, X.CODE,Z.CODE,M.DESCR 
    FROM TABLE_A A
    LEFT OUTER JOIN TABLE_Z Z
      ON A.REF_Z = Z.CODE
    LEFT OUTER JOIN TABLE_X X
      ON A.REF_X = X.CODE
    LEFT OUTER JOIN TABLE_M M
      ON Z.REF1 = M.Z_REF1
      AND Z.REF2 = M.Z_REF2
      AND Z.REF3 = M.Z_REF3
      AND X.REF1=M.X_REF1;

结果是:

在此处输入图片说明

按照预期的结果,我应该能够得到如图所示的图像,但是具有正确的组合显示。

哪件事对查询失败?

在那之后,这个想法也将以两种独立的观点出现。

我想一旦我有了正确的查询,我就能轻松地将其拆分。类似CORE_VIEW的视图,其中将包含TABLE_Z,TABLE_X和TABLE_M,而另一个视图将包含TABLE_A和CORE_VIEW。

这样就很容易实现代码的可重用性。


在Barry发表评论后,我能够生成正确的查询:

SELECT A.REF_X,A.REF_Z, X.CODE,Z.CODE,M.DESCR 
FROM TABLE_A A
LEFT OUTER JOIN TABLE_Z Z
  ON  A.REF_Z = Z.CODE
LEFT OUTER JOIN TABLE_X X
  ON  A.REF_X = X.CODE
LEFT OUTER JOIN TABLE_M M
  ON  (Z.REF1 = M.Z_REF1 OR (Z.REF1 IS NULL AND M.Z_REF1 IS NULL))
  AND (Z.REF2 = M.Z_REF2 OR (Z.REF2 IS NULL AND M.Z_REF2 IS NULL))
  AND (Z.REF3 = M.Z_REF3 OR (Z.REF3 IS NULL AND M.Z_REF3 IS NULL))
  AND (X.REF1 = M.X_REF1 OR (X.REF1 IS NULL AND M.X_REF1 IS NULL));

这给了我预期的结果:

在此处输入图片说明

The problem now is that ass said above I need to split it into a view by having TABLE_Z , TABLE_M and TABLE_Y into a sepparate view. If I directly split the query I see that I loose the results that I was having before... (I have splitted the query like below in order to have T1 as my new VIEW and had to change the order of the JOINS as I was leaving JOINS without ON clause...)

SELECT A.REF_X,A.REF_Z, T1.X_CODE, T1.Z_CODE, T1.DESCR
FROM TABLE_A A
LEFT OUTER JOIN 
    (SELECT X.CODE X_CODE,Z.CODE Z_CODE,M.DESCR  
    FROM TABLE_Z Z
    LEFT OUTER JOIN TABLE_M M
      ON  (Z.REF1 = M.Z_REF1 OR (Z.REF1 IS NULL AND M.Z_REF1 IS NULL))
      AND (Z.REF2 = M.Z_REF2 OR (Z.REF2 IS NULL AND M.Z_REF2 IS NULL))
      AND (Z.REF3 = M.Z_REF3 OR (Z.REF3 IS NULL AND M.Z_REF3 IS NULL))
    LEFT OUTER JOIN TABLE_X X  
      ON (X.REF1 = M.X_REF1 OR (X.REF1 IS NULL AND M.X_REF1 IS NULL))
    ) T1
ON   A.REF_X = T1.X_CODE
AND  A.REF_Z = T1.Z_CODE;

在此处输入图片说明

Is there any way I can split it into a sepparate View?

Alex Poole

You can't really do quite what you're attempting because of the AND in your outer join condition. You're partly back to the null equivalence issue rBarryYoung pointed out, but if you do that null check in your outer join, rather than in the inline view (you don't if there as none of your TABLE_X/Z refs are null), you get too many records back. This gets 16 rows, the ones you want plus some garbage:

SELECT A.REF_X, A.REF_Z, T1.X_CODE, T1.Z_CODE, T1.DESCR
FROM TABLE_A A
LEFT JOIN (
  SELECT X.CODE X_CODE,Z.CODE Z_CODE,M.DESCR
  FROM TABLE_M M
  LEFT JOIN TABLE_Z Z
  ON Z.REF1 = M.Z_REF1
  AND Z.REF2 = M.Z_REF2
  AND Z.REF3 = M.Z_REF3
  LEFT JOIN TABLE_X X
  ON X.REF1 = M.X_REF1
) T1
ON (T1.X_CODE = A.REF_X OR (T1.X_CODE IS NULL))
AND (T1.Z_CODE = A.REF_Z OR (T1.Z_CODE IS NULL));

If you just tried to split out the X_REF values:

SELECT M.CODE M_CODE, X.CODE X_CODE, M.DESCR
FROM TABLE_M M
LEFT JOIN TABLE_X X
ON X.REF1 = M.X_REF1

... you'd get 30 rows; and for X_CODE A you have four possible combinations, 1, 3, 5 or 7. For Z_REF it's similar:

SELECT M.CODE M_CODE, Z.CODE Z_CODE, M.DESCR
FROM TABLE_M M
LEFT JOIN TABLE_Z Z
ON Z.REF1 = M.Z_REF1
AND Z.REF2 = M.Z_REF2
AND Z.REF3 = M.Z_REF3

... gets 18 rows; and for Z_CODE Z you have three possible combinations, 1, 2 and 8. Now, you can compare those two lists and see that for the TABLE_A combination of A and Z the only overlapping combination is number 1, which is what you want.

But it breaks down because of the nulls. In the X_CODE list you get two null matches, for combinations 8 and 9. And in the Z_CODE list you get two null matches, for 7 and 9. Once you add the OR (T1.X_CODE IS NULL) and OR (T1.Z_CODE IS NULL) you get those as well, so for TABLE_A A and Z you get combinations 1 (where both A and Z match), 7 (A matches), 8 (Z matches) and 9 (neither matches).

And if you don't have the OR ... IS NULL conditions, you get the right answer when both TABLE_A columns match, but you don't get anything when either column doesn't match, as you saw in the results you included in the question. There isn't anything in between.

So you have to drive it from TABLE_A and join to TABLE_M via TABLE_X and TABLE_Z, as you're doing in your 'correct' query.

我唯一可以看到的视图就是使用子查询分解(也称为CTE)或实际视图,并使用具有四个分支的联合来处理可能的情况:

WITH T1 AS (
  SELECT X.CODE X_CODE,Z.CODE Z_CODE,M.DESCR
  FROM TABLE_M M
  LEFT JOIN TABLE_Z Z
  ON Z.REF1 = M.Z_REF1
  AND Z.REF2 = M.Z_REF2
  AND Z.REF3 = M.Z_REF3
  LEFT JOIN TABLE_X X
  ON X.REF1 = M.X_REF1
)
SELECT A.REF_X, A.REF_Z, T1.X_CODE, T1.Z_CODE, T1.DESCR
FROM TABLE_A A
JOIN T1 ON T1.X_CODE = A.REF_X AND T1.Z_CODE = A.REF_Z
UNION ALL
SELECT A.REF_X, A.REF_Z, T1.X_CODE, T1.Z_CODE, T1.DESCR
FROM TABLE_A A
JOIN T1 ON T1.X_CODE = A.REF_X AND T1.Z_CODE IS NULL
WHERE NOT EXISTS (SELECT 1 FROM T1 WHERE Z_CODE = A.REF_Z)
UNION ALL
SELECT A.REF_X, A.REF_Z, T1.X_CODE, T1.Z_CODE, T1.DESCR
FROM TABLE_A A
JOIN T1 ON T1.Z_CODE = A.REF_Z AND T1.X_CODE IS NULL
WHERE NOT EXISTS (SELECT 1 FROM T1 WHERE X_CODE = A.REF_X)
UNION ALL
SELECT A.REF_X, A.REF_Z, T1.X_CODE, T1.Z_CODE, T1.DESCR
FROM TABLE_A A
JOIN T1 ON T1.Z_CODE IS NULL AND T1.X_CODE IS NULL
WHERE NOT EXISTS (SELECT 1 FROM T1 WHERE X_CODE = A.REF_X OR Z_CODE = A.REF_Z);

会得到:

REF_X REF_Z X_CODE Z_CODE DESCR       
----- ----- ------ ------ ------------
A     Z     A      Z      COMBINATION1 
C     Y     C      Y      COMBINATION4 
D     U     D      U      COMBINATION3 
F     W     F      W      COMBINATION6 
A     FFF   A             COMBINATION7 
TTT   T            T      COMBINATION8 
SSS   JJJ                 COMBINATION9 

...但这很可怕,至少与您已有的工作相比。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

左外部联接和空值转换

来自分类Dev

左外部联接和空值转换

来自分类Dev

聚集查询的左外部联接

来自分类Dev

左外部联接具有空值

来自分类Dev

左外部联接linq结果中的空值导致错误

来自分类Dev

Ebean查询中的左外部联接

来自分类Dev

减少SQL查询中的左外部联接

来自分类Dev

Ebean查询中的左外部联接

来自分类Dev

使用左外部联接的唯一值?

来自分类Dev

Django左外部联接

来自分类Dev

在完全外部联接期间排除空值

来自分类Dev

在Linq查询中启用空值联接

来自分类Dev

ORACLE左外部联接问题(带有空表?)

来自分类Dev

Flask-SQLAlchemy左外部联接筛选查询

来自分类Dev

左外部联接查询非常慢-SQL Server

来自分类Dev

Linq左外部联接的查询无法正常工作

来自分类Dev

如何优化这个极其缓慢的左外部联接sqlite查询?

来自分类Dev

处理查询,以便在完全外部联接中不显示空值

来自分类Dev

MySQL“左外部联接”问题

来自分类Dev

左外部联接是否关联?

来自分类Dev

与Mongodb的多个左外部联接

来自分类Dev

删除重复的左外部联接

来自分类Dev

左外部联接是关联的吗?

来自分类Dev

如何实现左外部联接?

来自分类Dev

MySQL“左外部联接”问题

来自分类Dev

为左外部联接提供默认值

来自分类Dev

MySQL左外部联接不为COUNT(*)返回NULL值

来自分类Dev

一次在左外部联接中显示重复值

来自分类Dev

SQL外部查询值插入嵌套子查询联接