SQL 正在生成 CROSS JOIN 但我想要 INNER JOIN(记录成倍增加)

1 join sql-server

  SELECT *
  FROM        GRNHISTORY GR
  inner Join Inventorytransferlog itl on GR.ReferenceEntryID=itl.ReferenceEntryID
Run Code Online (Sandbox Code Playgroud)

GRNHISTORYInventorytransferlog两个表都有自己的 ID 列和唯一 ID。但是我们不需要它,也没有使用它。 ReferenceEntryIDforeign key从其他表。两个表都有 10 条记录。现在,当我运行此查询时,它向我显示了 100 条我似乎无法理解的记录。根据我的理解,它应该显示 10 条记录。请纠正我的错误。

Vér*_*ace 6

当为PRIMARY KEY您要连接的两个表的s插入有效值并查看结果时,答案变得显而易见:

一个例子:

两个表:

CREATE TABLE fred (int_1 INTEGER, ref1 INTEGER);   -- equivalent of GRNHISTORY
CREATE TABLE bill (int_2 INTEGER, ref2 INTEGER);   -- of Inventorytransferlog
Run Code Online (Sandbox Code Playgroud)

数据:

INSERT INTO fred VALUES (1, 55), (2, 56), (3, 57);
INSERT INTO bill VALUES (21, 55), (22, 56), (23, 57); 
       -- NOTE: only 1 matching value of the JOINing refrerence field per table!
       -- and NOTE: different PRIMARY KEYs for the two tables! 
Run Code Online (Sandbox Code Playgroud)

(你的)SQL:

SELECT * FROM fred f
INNER JOIN bill b ON f.ref1 = b.ref2
Run Code Online (Sandbox Code Playgroud)

结果(和小提琴):

int1 ref1 int2 ref2
   1   55   21   55
   2   56   22   56
   3   57   23   57
Run Code Online (Sandbox Code Playgroud)

但是,如果数据现在更改如下:

INSERT INTO fred VALUES (1, 55), (2, 55), (3, 55);
INSERT INTO bill VALUES (21, 55), (22, 55), (23, 55);  

       -- NOTE: 55 - ALL the values of JOINing reference columns in each record match!
Run Code Online (Sandbox Code Playgroud)

请注意,现在连接字段在所有记录的两个表中都具有相同的值,然后运行上述相同的SQL。结果(和小提琴):

  int1  ref1 int1 ref2
    1   55  21  55
    2   55  21  55
    3   55  21  55
    1   55  22  55
    2   55  22  55
    3   55  22  55
    1   55  23  55
    2   55  23  55
    3   55  23  55
Run Code Online (Sandbox Code Playgroud)

结果是 9(即 3 x 3)条记录(有效),CROSS JOIN因为您的数据使其如此!因为您已经要求 SQL 处理BOTH表中JOIN非常常见的值,因此您可以预期结果中有很多记录!

您可以通过执行以下操作来检查这一点

SELECT COUNT(DISTINCT(ref1)) AS distinct_ref FROM fred;
Run Code Online (Sandbox Code Playgroud)

answer = 1,(对于带有 ref2 的 bill 的结果相同)。

我敢打赌,在您获得 a CROSS JOIN(或非常相似的东西)的表中,使用上面的 SQLReferenceEntryID将使您获得非常低的计数(这两个表中也匹配),从而导致SELECT.

有对你明显的乘法的解释,或者CROSS JOIN- 你在两个表中有太多匹配的记录 - 等等!