SQL Server JOIN不返回任何行

时间:2018-12-20 10:39:07

标签: sql sql-server tsql

所以我的数据库中有这种情况:

SELECT A.No_ as itemno,A.Description as description from
[dbo].[PRUEBAS$Item] A
WHERE (A.No_ LIKE  '020212601%' COLLATE Modern_Spanish_100_CI_AI 
or A.Description LIKE '%020212601%' COLLATE  Modern_Spanish_100_CI_AI);

仅返回一行

+-----------+-------------+
|  itemno   | description |
+-----------+-------------+
| 020212601 | BLA BLA     |
+-----------+-------------+

我的第二张表返回此:

select * from [dbo].[PRUEBAS$Item Cross Reference] B 
where B.[Item No_] LIKE  '020212601%' COLLATE Modern_Spanish_100_CI_AI ;

+-----------+----------------------+---------------------+--+
| Item No_  | Cross-Reference Type | Cross-Reference No_ |  |
+-----------+----------------------+---------------------+--+
| 020212601 |                    2 |                     |  |
| 020212601 |                    2 |           020212601 |  |
| 020212601 |                    2 |                     |  |
| 020212601 |                    2 |           020212601 |  |
+-----------+----------------------+---------------------+--+

现在我同时加入两个表:

select A.No_ as itemno,A.Description as description, A.[Producto M3] as m3item  from
[dbo].[PRUEBAS$Item] A left outer join [dbo].[PRUEBAS$Item Cross Reference] B 
on A.No_ = B.[Item No_] 
WHERE (A.No_ LIKE  '020212601%' COLLATE Modern_Spanish_100_CI_AI 
or A.Description LIKE '%020212601%' COLLATE  Modern_Spanish_100_CI_AI 
or B.[Cross-Reference No_] LIKE  '020212601%' COLLATE Modern_Spanish_100_CI_AI)

我得到:

+-----------+-------------+--------+
|  itemno   | description | m3item |
+-----------+-------------+--------+
| 020212601 | BLA BLA     |      0 |
| 020212601 | BLA BLA     |      0 |
| 020212601 | BLA BLA     |      0 |
| 020212601 | BLA BLA     |      0 |
+-----------+-------------+--------+

这意味着我的相关表有4行。

我下一步要做的是在WHERE子句中添加一个过滤器,因为我不想在第二个表中添加一些数据:

select A.No_ as itemno,A.Description as description, A.[Producto M3] as m3item  from
[dbo].[PRUEBAS$Item] A left outer join [dbo].[PRUEBAS$Item Cross Reference] B 
on A.No_ = B.[Item No_] 
WHERE (A.No_ LIKE  '020212601%' COLLATE Modern_Spanish_100_CI_AI 
or A.Description LIKE '%020212601%' COLLATE  Modern_Spanish_100_CI_AI 
or B.[Cross-Reference No_] LIKE  '020212601%' COLLATE Modern_Spanish_100_CI_AI) 
and (B.[Cross-Reference Type] = 3)

这根本不返回任何行!我本来希望排成一行,因为我正在使用LEFT OUTER JOIN。

我缺少什么?即使第二张表中没有记录,我也需要一行

3 个答案:

答案 0 :(得分:1)

尝试将对WHERE子句中第二个表的限制移动到联接本身的ON子句中:

SELECT
    A.No_ AS itemno,
    A.Description AS description,
    A.[Producto M3] AS m3item
FROM [dbo].[PRUEBAS$Item] A
LEFT JOIN [dbo].[PRUEBAS$Item Cross Reference] B
    ON A.No_ = B.[Item No_] AND
       B.[Cross-Reference No_] LIKE '020212601%' COLLATE Modern_Spanish_100_CI_AI
WHERE
    (A.No_ LIKE '020212601%' COLLATE Modern_Spanish_100_CI_AI OR
     A.Description LIKE '%020212601%' COLLATE  Modern_Spanish_100_CI_AI) AND
    [Cross-Reference Type] = 3;

当前查询的问题在于,WHERE子句中出现的第二张表上的限制可能导致在查询完成之前过早地滤除不匹配的记录。以上建议可以解决这个问题。

答案 1 :(得分:1)

我相信您想要的查询是:

select A.No_ as itemno,A.Description as description, A.[Producto M3] as m3item 
from [dbo].[PRUEBAS$Item] A left outer join
     [dbo].[PRUEBAS$Item Cross Reference] B 
     on A.No_ = B.[Item No_] and
        B.[Cross-Reference Type] = 3
WHERE (A.No_ LIKE  '020212601%' COLLATE Modern_Spanish_100_CI_AI) or 
      (A.Description LIKE '%020212601%' COLLATE  Modern_Spanish_100_CI_AI) or 
      (B.[Cross-Reference No_] LIKE  '020212601%' COLLATE Modern_Spanish_100_CI_AI) ;

您在第二张桌子上的情况很复杂。需要将条件= 3放入on子句中,因为它引用了所有行。其他条件作为or条件的一部分是可选的,因此它可以保留在WHERE子句中。

答案 2 :(得分:1)

很遗憾,您的数据样本未提供所有需要的列,并且没有提供所需的DDL。尽管如此,原始查询中仍存在引用左连接表的过滤谓词。

虽然您可能期望有一行,但我相信将别名B的谓词移到联接中可以得到2或4。

CREATE TABLE PRUEBAS$Item(
   No_      varchar(20)  NOT NULL
  ,description VARCHAR(13) NOT NULL
  ,[Producto M3]      VARCHAR(30)
);
INSERT INTO PRUEBAS$Item(No_,description) VALUES ('020212601','BLA BLA');

CREATE TABLE [PRUEBAS$Item Cross Reference](
   Item_No_             varchar(20)  NOT NULL
  ,CrossReference_Type  INTEGER  NOT NULL
  ,CrossReference_No_   varchar(20) 
  ,[Cross-Reference Type] INTEGER

);
INSERT INTO [PRUEBAS$Item Cross Reference](Item_No_,CrossReference_Type,CrossReference_No_,[Cross-Reference Type]) VALUES ('020212601',2,NULL,3);
INSERT INTO [PRUEBAS$Item Cross Reference](Item_No_,CrossReference_Type,CrossReference_No_,[Cross-Reference Type]) VALUES ('020212601',2,'020212601',3);
INSERT INTO [PRUEBAS$Item Cross Reference](Item_No_,CrossReference_Type,CrossReference_No_,[Cross-Reference Type]) VALUES ('020212601',2,NULL,3);
INSERT INTO [PRUEBAS$Item Cross Reference](Item_No_,CrossReference_Type,CrossReference_No_,[Cross-Reference Type]) VALUES ('020212601',2,'020212601',3);
SELECT
    A.No_           AS itemno
  , A.Description   AS description
  , A.[Producto M3] AS m3item
  , b.*
FROM [dbo].[PRUEBAS$Item] A
LEFT OUTER JOIN [dbo].[PRUEBAS$Item Cross Reference] B ON A.No_ = B.[Item_No_]
    AND B.[CrossReference_No_] LIKE '020212601%' COLLATE Modern_Spanish_100_CI_AI
    AND (B.[Cross-Reference Type] = 3)
WHERE (A.No_ LIKE '020212601%' COLLATE Modern_Spanish_100_CI_AI
    OR A.Description LIKE '%020212601%' COLLATE Modern_Spanish_100_CI_AI
    )
;

GO
itemno    | description | m3item | Item_No_  | CrossReference_Type | CrossReference_No_ | Cross-Reference Type
:-------- | :---------- | :----- | :-------- | ------------------: | :----------------- | -------------------:
020212601 | BLA BLA     | null   | 020212601 |                   2 | 020212601          |                    3
020212601 | BLA BLA     | null   | 020212601 |                   2 | 020212601          |                    3
SELECT
    A.No_           AS itemno
  , A.Description   AS description
  , A.[Producto M3] AS m3item
  , b.*
FROM [dbo].[PRUEBAS$Item] A
LEFT OUTER JOIN [dbo].[PRUEBAS$Item Cross Reference] B ON A.No_ = B.[Item_No_]
    AND (B.[Cross-Reference Type] = 3)
WHERE (A.No_ LIKE '020212601%' COLLATE Modern_Spanish_100_CI_AI
    OR A.Description LIKE '%020212601%' COLLATE Modern_Spanish_100_CI_AI
    OR B.[CrossReference_No_] LIKE '020212601%' COLLATE Modern_Spanish_100_CI_AI
    )
;
itemno    | description | m3item | Item_No_  | CrossReference_Type | CrossReference_No_ | Cross-Reference Type
:-------- | :---------- | :----- | :-------- | ------------------: | :----------------- | -------------------:
020212601 | BLA BLA     | null   | 020212601 |                   2 | null               |                    3
020212601 | BLA BLA     | null   | 020212601 |                   2 | 020212601          |                    3
020212601 | BLA BLA     | null   | 020212601 |                   2 | null               |                    3
020212601 | BLA BLA     | null   | 020212601 |                   2 | 020212601          |                    3

db <>提琴here

并非所有列名都与您的原始名称完全一致(空格很麻烦!)