【问题标题】:SQL Query is creating way too many repeated rowsSQL Query 正在创建太多重复的行
【发布时间】:2020-05-03 09:45:24
【问题描述】:

我有一个关于 sql 查询以及如何显示输出的问题,你看,我有 3 个表并且至少有一个共同的字段,问题是当我将 2 个表连接在一起时,我需要的信息就会显示出来正确,但是当我加入第三个时,输出变得疯狂并且重复结果太多,我需要弄清楚它为什么会发生,下面我将向您展示所有表格和彼此之间的关系

这就是表格相互关联的方式

这是第一个表 (dbo_predios) 的制作方式,在这种情况下,前三个字段是唯一相关的

这就是第二个表(dbo_permisos_obras_mayores)的制作方式,前三个字段在这种情况下也是唯一相关的,后两个可以匹配第一个表(dbo_predios)

第三个表 (dbo_recepciones_obras_mayores) 是如何制作的,第四个字段在这种情况下是唯一相关的,它可能与第二个表 (dbo_permisos_obras_mayores) 的同名字段相关

好的,现在从结构上讲,现在我正在执行的查询如下:

SELECT
dbo_predios.codigo_unico_predio,
dbo_permisos_obras_mayores.numero_permiso_edificacion,
dbo_permisos_obras_mayores.fecha_permiso_edificacion
FROM dbo_predios
INNER JOIN  dbo_permisos_obras_mayores ON dbo_predios.codigo_manzana_predio = dbo_permisos_obras_mayores.codigo_manzana_predio AND dbo_predios.codigo_lote_predio = dbo_permisos_obras_mayores.codigo_lote_predio
INNER JOIN  dbo_recepciones_obras_mayores ON dbo_permisos_obras_mayores.numero_recepcion_permiso = dbo_recepciones_obras_mayores.numero_recepcion_permiso
WHERE       dbo_permisos_obras_mayores.codigo_manzana_predio = 9402 AND dbo_permisos_obras_mayores.codigo_lote_predio = 30

而这样执行查询的结果是这样的:

后来我做了一些试验和错误并删除了第二个内部连接线,结果让我感到惊讶,这就是发生的事情:

结论:简而言之,第三个表是导致笛卡尔积的原因,为什么?我希望我知道为什么,您如何看待这个特殊情况?我会感谢你能给我的任何帮助,在此先感谢。

【问题讨论】:

  • 轻松为您提供帮助,您将更快地获得更好的帮助。 (minimal reproducible example)
  • 我强烈建议在FROM 中为您的表(名称很长)提供别名,然后在您对列的引用中使用这些别名;它会使它更具可读性。 (另外,为什么你的表在dbo_ 上有前缀,而它们也在dbo 架构上?)
  • 嗨@Larnu,这就是他们在这里写的方式,我对此无能为力,我们必须重命名大约 500 个或更多的表,我想这应该是易于阅读或识别,我知道这是多余的,但这是数据库的制作方式
  • 嗨@cdrrr 正如我在之前的评论中所说,也许不是最好的方法,但我正在工作的整个数据库都有数字 PK 所以我做了同样的事情来改善表之间的关系
  • 您没有在查询中使用任何笛卡尔积。您要么有多个 numero_recepcion_permisopermisos_obras_mayores 表匹配,要么您缺少最后两个表之间的另一个链接。在您的查询中包含numero_recepcion_permiso 并验证发生了什么。

标签: sql sql-server database sql-server-2008-r2 inner-join


【解决方案1】:

这是解决方案 - 既然您说 numero_recepcion_permiso 是空白的,只需将条件添加到内部连接中,以排除空的:

SELECT
dbo_predios.codigo_unico_predio,
dbo_permisos_obras_mayores.numero_permiso_edificacion,
dbo_permisos_obras_mayores.fecha_permiso_edificacion
FROM dbo_predios
INNER JOIN  dbo_permisos_obras_mayores ON dbo_predios.codigo_manzana_predio = dbo_permisos_obras_mayores.codigo_manzana_predio AND dbo_predios.codigo_lote_predio = dbo_permisos_obras_mayores.codigo_lote_predio
INNER JOIN  dbo_recepciones_obras_mayores ON dbo_permisos_obras_mayores.numero_recepcion_permiso = dbo_recepciones_obras_mayores.numero_recepcion_permiso 
            AND dbo_recepciones_obras_mayores.numero_recepcion_permiso <>''
WHERE       dbo_permisos_obras_mayores.codigo_manzana_predio = 9402 AND dbo_permisos_obras_mayores.codigo_lote_predio = 30

话虽如此,该字段应该允许为空白还是NULL?也许您需要向您的表添加一个约束来防止这种情况。另一个建议 - 为什么选择 NUMERIC(18,0) 作为这些表的主键数据类型?我更喜欢简单的INTBIGINT,也许让数据库为我生成序列。

【讨论】:

  • 嗨@Icarus,感谢您的查询,效果很好,但在某些情况下,我也需要相同的查询而不需要 where 并且获取非常重复的数据,有什么办法可以做到这一点我怎么摆姿势?
  • @сꝛıϻѕοɴᴠᴇɴoϻ 我不确定我是否遵循without the where(?)的意思。我没有在where 子句中添加AND 条件;我将它添加到INNER JOIN,因此您应该能够消除WHERE 子句并且JOIN 仍然可以正常工作,除了这次,对于所有predios 而不仅仅是特定的。但我确定我误解了你的问题......:/
  • 终于成功了,我做了一些小的调整,一切都很好,感谢您的时间和帮助。
【解决方案2】:

好的,我按照伊卡洛斯告诉我的做了,我发现了一些有用的东西,你看,我犯了一个大错误,我尝试的数字组合没有numero_recepcion_permiso,所以输出列完全是空白,但是当有一个实际的numero_recepcion_permiso 它显示正确时,无论如何我仍然需要它不会输出那么多重复的行,我该如何解决这个问题?谢谢大家到目前为止的帮助

【讨论】:

    【解决方案3】:

    首先,确保两个值都存在于两个字段中并且它们实际上匹配,否则可能会生成重复行的数量,但是重复行的数量是我无法判断的,因为我不知道是什么你的实际数据是,但这可能会解决一点问题

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-10
      • 1970-01-01
      • 2020-03-29
      • 2021-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多