Mysql 内部联接和分组方式以防止重复结果 背景:

Mysql 内部联接和分组方式以防止重复结果 背景:,mysql,orm,group-by,Mysql,Orm,Group By,我正在开发一个简单的ORM(用于PHP),它基于静态配置自动化大多数查询 因此,从表和实体定义中,库自动处理联接并生成适当的字段/表别名。。。对于左联接没有问题,但在一对多的关系中,内部联接可能会导致重复的结果。 我的想法是在必要时自动添加GROUPBY子句(在自动递增键上) 问题 如果我认为需要加入一个GROUPBY子句(如果只有)连接是否在ON上,并且条件与匹配表的唯一键不匹配,那么是否正确? 例子 这是一个非常简单的示例,其中我希望选择(至少)具有关联显示的所有事件。 如果没有内部连接,还

我正在开发一个简单的ORM(用于PHP),它基于静态配置自动化大多数查询

因此,从表和实体定义中,库自动处理联接并生成适当的字段/表别名。。。对于左联接没有问题,但在一对多的关系中,内部联接可能会导致重复的结果。 我的想法是在必要时自动添加GROUPBY子句(在自动递增键上)

问题

如果我认为需要加入一个GROUPBY子句(如果只有)连接是否在ON上,并且条件与匹配表的唯一键不匹配,那么是否正确?

例子 这是一个非常简单的示例,其中我希望选择(至少)具有关联显示的所有事件。 如果没有内部连接,还有其他方法可以做到这一点,我很想知道如何做到:)

谢谢

数据显示,“我的酷活动”正在公园和学校举行。如果将表内部联接,将得到多个结果

执行此查询以查看发生了什么:

Select t.*, t1.* FROM `Event` t INNER JOIN `Showing` t1 ON t.Id=t1.`EventId`;
这是与重复查询相同的查询,但从两个表中选择列

第一行结果显示,这项活动正在公园举行。第二行说同样的事件正在学校发生。

(这应该是一个评论,但有点长)

对于左联接没有问题,但在一对多的关系中,内部联接可能会导致重复的结果

从这句话中可以清楚地看出,我们中至少有一个人对关系数据库如何工作以及对象-关系映射应该如何工作感到非常困惑

导致重复值的查询

生成的行不是重复的-您编写了查询,因此它不会显示它们不同的原因:

SELECT t1.place, t.* 
FROM Event 
INNER JOIN Showing 
ON Event.Id=Showing.EventId;
如果您对“显示”中的数据不感兴趣,那么为什么它会出现在您的查询中?如果您有没有相关显示记录的事件,那么您应该使用“存在”-而不是联接(考虑您有单个事件但有300万次显示的情况)


如果您严格地实现了ORM,那么您可能根本不应该编写带有连接的查询——但依我看,使用工厂更好地服务于该场景

不要这样做,使用composer并下载一个已经可用的简单orm这不是重点,我不会讨论为什么我要创建自己的orm,可能是为了好玩,可能是为了学习,可能是挑战或只是愚蠢。。。不管怎样,你不回答我的问题,让我无法理解:)你为什么不使用
选择distinct
,而不是
分组方式?此外,考虑用户需要什么:如果用户正在查询一对多关系表,他们可能愿意接受(或甚至可能需要)重复行。感谢独特的技巧,它工作得很好!关于需求,这只是我第一次关心。我的主要目标不是建议其他ORM做什么(dynamic是正确的),而是尝试仅从静态表/实体定义自动化最常见的查询!简单查询、关联字段、计数、链接表。。。对于更复杂的工作,手工编写查询或使用“专业”ORM:)完美!EXISTS正是我在本例中需要的:)然而,我并不是说结果出乎意料,只是这不是所需的结果,因为我正在制作ORM,这意味着结果必须转换为唯一的实体。连接有时很有用,例如,如果我需要从另一个表中获取一些“只读”信息,如实体的父名称、子项计数等。没有与此示例的链接(对于此示例,EXISTS是最佳解决方案):在场景中,我需要从外部表获取一些信息,然后我将使用连接。关于分组和唯一约束关系,我最初的问题是什么?我可以把请求看作安全的(=只返回一个结果),从定义为唯一约束的所有字段与ON/WHERE子句中的常量值进行比较吗?是的,如果我需要从第二个表中获取数据,我会这样做。但是正如symbacbean所提到的,使用WHERE-EXISTS比在相反的情况下使用连接要好得多。无论如何,感谢您的澄清:)
SELECT t1.place, t.* 
FROM Event 
INNER JOIN Showing 
ON Event.Id=Showing.EventId;
SELECT t1.place, t.* 
FROM `Event` t 
WHERE EXISTS (SELECT 1
  FROM Showing
  WHERE Event.Id=Showing.EventId);