【问题标题】:SQL Left Join returns less than expectedSQL Left Join 返回的结果少于预期
【发布时间】:2013-08-17 23:55:38
【问题描述】:

我有一个数据库,我需要获取表 PEDIDOC 上与 FALTANTE 混合的数据,但我需要进行左连接,因为即使没有匹配的 FALTANTE,我也需要 PEDIDOC 中的所有数据。我进行了三次检查,所有信息都正确输入,一切都在那里,如果我只是做 Select * FROM pedidoc,我在 Excel 中过滤它时得到了我期望的结果,但是当我做左连接时,就会缺少产品。

这里是查询

SELECT
        `pedidoc`.`fecha`,
        `pedidoc`.`IdPedido`, `pedidoc`.`plaza`, `pedidoc`.`IdProducto`,
        `pedidoc`.`Categoria`,`pedidoc`.`Pedido`,`faltante`.`faltante`
FROM `pedidoc`
        LEFT JOIN `caducidad` ON `pedidoc`.`IdProducto`=`faltante`.`IdProducto`
GROUP BY `pedidoc`.`fecha`, `pedidoc`.`IdProducto`

这是数据库

CREATE TABLE Faltante (
    IdProducto DECIMAL(17,0) NOT NULL,
    Plaza VARCHAR(40) NOT NULL,
    Fecha VARCHAR(10) NOT NULL,
    Faltante INT NULL,
    FOREIGN KEY(IdProducto) REFERENCES Producto(IdProducto),
    UNIQUE(IdProducto, Fecha, Plaza)
)Engine=InnoDB;

CREATE TABLE pedidoc (
    IdProducto DECIMAL(17,0) NOT NULL,
    IdPedido VARCHAR(40) NOT NULL,
    Plaza VARCHAR(40) NOT NULL,
    Fecha VARCHAR(10) NOT NULL,
    Categoria VARCHAR(40) NOT NULL,
    Pedido INT NULL,
    FOREIGN KEY(IdProducto) REFERENCES Producto(IdProducto),
    UNIQUE(IdProducto, Fecha, Plaza)
)Engine=InnoDB;

它返回的数据是正确的(随机抽取了一些样本),但它丢失了 pedidoc 中一半以上的数据。

我的查询有什么问题?

仅供参考,我在我的测试机器和 WAMP 堆栈上运行 Windows 8。

大家好, 古斯塔沃

EDIT> 这是我在“第一”天得到的表格。问题是它每天只需要一种产品,而实际上每个广场每天都有一种产品。应该有一个产品列表,每个广场几乎相同,但对于蒙特雷来说只显示 2 个,而不是所有产品

fecha           IdPedido    plaza   IdProducto  Categoria   Pedido  caducidad
01/01/2012  2589970-20  Mexico  4111    Bigdonuts   0   0
01/01/2012  2589970-20  Mexico  7920    Bigdonuts   406 0
01/01/2012  2589970-20  Mexico  7921    Bigdonuts   425 0
01/01/2012  2589970-20  Mexico  7922    Bigdonuts   712 0
01/01/2012  2589970-20  Mexico  7923    Bigdonuts   454 0
01/01/2012  2589970-20  Mexico  7924    Bigdonuts   31  0
01/01/2012  2589970-20  Mexico  7925    Bigdonuts   11  0
01/01/2012  2589970-20  Mexico  7926    Bigdonuts   147 0
01/01/2012  2590100-10  Monterrey   7928    Bigdonuts   128 0
01/01/2012  2590100-10  Monterrey   7929    Bigdonuts   70  0
01/01/2012  2590090-30  Reynosa 7931    Big Donuts  12  0
01/01/2012  2590090-30  Reynosa 7932    Big Donuts  154 0
01/01/2012  2590090-30  Reynosa 7933    Big Donuts  23  0
01/01/2012  2590090-30  Reynosa 7934    Big Donuts  169 0
01/01/2012  2590090-30  Reynosa 7935    Big Donuts  50  0
01/01/2012  2589970-20  Mexico  7936    Bigdonuts   352 0
01/01/2012  2590100-10  Monterrey   7937    Bigdonuts   0   0
01/01/2012  2590090-30  Reynosa 7938    Big Donuts  296 0
01/01/2012  2590090-30  Reynosa 7939    Big Donuts  12  0
01/01/2012  2590080-50  Saltillo    7941    Bigdonuts   64  0
01/01/2012  2590080-50  Saltillo    7942    Bigdonuts   38  0
01/01/2012  2589970-20  Mexico  7944    Bigdonuts   269 0
01/01/2012  2589970-20  Mexico  7945    Bigdonuts   284 0
01/01/2012  2589970-20  Mexico  7946    Bigdonuts   320 0
01/01/2012  2589970-20  Mexico  7954    Bigdonuts   0   0
01/01/2012  2589970-20  Mexico  7969    Bigdonuts   334 0
01/01/2012  2589970-20  Mexico  7970    Bigdonuts   246 0
01/01/2012  2589970-20  Mexico  7971    Bigdonuts   39  0
01/01/2012  2589970-20  Mexico  7972    Bigdonuts   327 0
01/01/2012  2589970-20  Mexico  8071    Bigdonuts   0   0
01/01/2012  2590080-50  Saltillo    8112    Bigdonuts   0   0
01/01/2012  2590080-50  Saltillo    8113    Bigdonuts   0   0
01/01/2012  2590080-50  Saltillo    8114    Bigdonuts   0   0
01/01/2012  2590080-50  Saltillo    8115    Bigdonuts   0   0
01/01/2012  2590080-50  Saltillo    8116    Bigdonuts   0   0
01/01/2012  2590080-50  Saltillo    8117    Bigdonuts   0   0
01/01/2012  2589970-20  Mexico  8212    Bigdonuts   0   0
01/01/2012  2589970-20  Mexico  8453    Bigdonuts   0   0
01/01/2012  2589970-20  Mexico  8454    Bigdonuts   0   0
01/01/2012  2589970-20  Mexico  8456    Bigdonuts   0   0
01/01/2012  2589970-20  Mexico  8457    Bigdonuts   0   0
01/01/2012  2590100-10  Monterrey   68895   Bigdonuts   0   0

【问题讨论】:

  • 您能否将数据发布到缺少的几条记录中?
  • 顺便说一句,在您的查询中,您将 pedidoc 表与 caducidad 表连接,而不是 Faltante。
  • 我认为问题中的 SQL 语句实际上不会执行,因为 select 中的某些字段不在 group by 或聚合语句的一部分中。
  • 很抱歉,我把语句放在这里时打错了,但它确实执行了,我将把它给出的第 1 天的表格粘贴到主帖上

标签: mysql sql left-join


【解决方案1】:

只是改变

GROUP BY `pedidoc`.`fecha`, `pedidoc`.`IdProducto`

GROUP BY pedidoc.IdProducto, pedidoc.fecha, pedidoc.Plaza

因此它与pedidoc 上的UNIQUE 约束相匹配,从而确保pedidoc 的每一行都恰好出现一次。

(注意:您的查询,无论是否有此更改,都不能移植到其他 DBMS,因为它取决于特殊的 MySQL 行为;请参阅§12.17.3 "MySQL Extensions to GROUP BY" in the MySQL 5.6 Reference Manual。我假设这没关系?)

【讨论】:

  • 谢谢!!真的解决了问题!!我也很清楚它只适用于 MySQL,并且我不使用 DBMS 的一些最佳实践,但由于我总是使用 LAMP 或 WAMP,它已经足够好了。我可能会在几个月后迁移到 postgresql,但它将在代码方面进行重建。
【解决方案2】:

GROUP BY 是为了减少行数

我想你想要 ORDER BY

如果您只想消除重复记录,可以使用 SELECT DISTINCT。只需在 SELECT 关键字之后添加 DISTINCT 关键字,如下所述:http://www.w3schools.com/sql/sql_distinct.asp

但是,我不确定这是否会给你想要的东西。 ruakh 认为这是一个不可移植的扩展是正确的,更重要的是,正如 ruakh 回答的参考资料中所指出的那样,GROUP BY 会将所有记录中的每个字段的值都相同的所有记录分组到一个记录中分组依据。

对于 SELECT 中提及但 GROUP BY 中未提及的任何字段,MySQL 将随机选择这些记录中这些字段的任何值。如果所有这些记录对这些字段具有相同的值,则选择哪条记录无关紧要。例如,在您上面的示例数据中,Categoria 是 Bigdonuts 的所有第一组 8 条记录与 plaza of Mexico,因此选择哪个 Categoria 值并不重要。

但是,对于 Pedido,显示了几个不同的值,包括 0、406 和 425。MySQL 将随机选择这八个不同的值之一。我无法想象这就是你想要的。

这就是为什么,一般来说,除非您知道在 GROUP BY 中分组的所有记录都具有相同的字段值,否则您可能希望使用聚合函数之一,例如 SUM、COUNT 等。 :http://www.w3schools.com/sql/sql_functions.asp

【讨论】:

  • 我使用 group by 因为某种原因数据被重复了大约 400 次。但我明白你的意思,这可能是问题的一部分。但是我怎样才能在没有太多重复的情况下实现 LEFT JOIN 呢?我应该更改我的数据库结构并重新输入所有数据吗?
  • 感谢您的解释并完全同意您所说的,但是对于这种情况,Group by 可以解决问题,因为我不介意不可移植性。我已经检查过了,所有 IdProducto 每天都会出现在每个广场,所以虽然它可能不是“技术上”正确的,但它正在工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-06
  • 2021-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多