SQL Server:连接4个表的重复项

SQL Server:连接4个表的重复项,sql,sql-server,join,duplicates,Sql,Sql Server,Join,Duplicates,我有四张桌子 客户-PK:客户ID Events-PK:EventID Customers\u Events-包含两个FK的联接表CustomerID和EventID Customer\u Checkins-包含时间戳列(CheckinDateTime)和对CustomerID的FK引用 我想要这样的输出 CustomerName EventName CheckinDateTime ------------ ---------- --------------- Peter

我有四张桌子

  • 客户
    -PK:
    客户ID
  • Events
    -PK:
    EventID
  • Customers\u Events
    -包含两个FK的联接表
    CustomerID
    EventID
  • Customer\u Checkins
    -包含时间戳列(
    CheckinDateTime
    )和对
    CustomerID的FK引用
我想要这样的输出

CustomerName   EventName    CheckinDateTime
------------   ----------   ---------------
Peter          Christmas    2012-12-25 00:27:48.350
Peter          Valentines   2013-02-14 01:19:36.113
Peter          Spring       2013-05-20 02:13:53.710
问题是我得到了这个结果

CustomerName   EventName    CheckinDateTime
------------   ----------   ---------------
Peter          Christmas    2012-12-25 00:27:48.350
Peter          Christmas    2013-02-14 01:19:36.113
Peter          Christmas    2013-05-20 02:13:53.710
Peter          Valentines   2012-12-25 00:27:48.350
Peter          Valentines   2013-02-14 01:19:36.113
Peter          Valentines   2013-05-20 02:13:53.710
Peter          Spring       2012-12-25 00:27:48.350
Peter          Spring       2013-02-14 01:19:36.113
Peter          Spring       2013-05-20 02:13:53.710
每个有效记录返回三次

这是我用来获得上述结果的脚本

SELECT DISTINCT 
    Customers.Firstname, Events.EventName, CustomerCheckins.CheckinDateTime
FROM         
    CustomerCheckins 
INNER JOIN
    Customers_Events ON CustomerCheckins.CustomerID = Customers_Events.CustomerID 
LEFT OUTER JOIN
    Customers ON Customers_Events.CustomerID = Customers.CustomerID 
RIGHT OUTER JOIN
    Events ON Customers_Events.EventID = Events.EventID
WHERE     
    (Customers_Events.CustomerID = 1887)

如果能帮我解决这个问题,我将不胜感激。我觉得我已经尝试了剧本中的每一个组合

您应该使用
分组
而不是
独立

SELECT Customers.Firstname, Events.EventName, MIN(CustomerCheckins.CheckinDateTime)
FROM         
    CustomerCheckins 
        INNER JOIN Customers_Events ON CustomerCheckins.CustomerID = Customers_Events.CustomerID 
        INNER JOIN Customers ON Customers_Events.CustomerID = Customers.CustomerID 
        INNER JOIN Events ON Customers_Events.EventID = Events.EventID
WHERE Customers_Events.CustomerID = 1887
GROUP BY Customers.Firstname, Events.EventName

您应该使用
分组
而不是
独立

SELECT Customers.Firstname, Events.EventName, MIN(CustomerCheckins.CheckinDateTime)
FROM         
    CustomerCheckins 
        INNER JOIN Customers_Events ON CustomerCheckins.CustomerID = Customers_Events.CustomerID 
        INNER JOIN Customers ON Customers_Events.CustomerID = Customers.CustomerID 
        INNER JOIN Events ON Customers_Events.EventID = Events.EventID
WHERE Customers_Events.CustomerID = 1887
GROUP BY Customers.Firstname, Events.EventName

您应该使用
分组
而不是
独立

SELECT Customers.Firstname, Events.EventName, MIN(CustomerCheckins.CheckinDateTime)
FROM         
    CustomerCheckins 
        INNER JOIN Customers_Events ON CustomerCheckins.CustomerID = Customers_Events.CustomerID 
        INNER JOIN Customers ON Customers_Events.CustomerID = Customers.CustomerID 
        INNER JOIN Events ON Customers_Events.EventID = Events.EventID
WHERE Customers_Events.CustomerID = 1887
GROUP BY Customers.Firstname, Events.EventName

您应该使用
分组
而不是
独立

SELECT Customers.Firstname, Events.EventName, MIN(CustomerCheckins.CheckinDateTime)
FROM         
    CustomerCheckins 
        INNER JOIN Customers_Events ON CustomerCheckins.CustomerID = Customers_Events.CustomerID 
        INNER JOIN Customers ON Customers_Events.CustomerID = Customers.CustomerID 
        INNER JOIN Events ON Customers_Events.EventID = Events.EventID
WHERE Customers_Events.CustomerID = 1887
GROUP BY Customers.Firstname, Events.EventName

问题在于您的数据库设计

您的数据模型不允许您将签入链接到特定事件

如果事件表包含startdate和enddate,则问题是可以解决的; 然后可以在联接中添加时间约束

编辑:

幸运的是,事件表中有startdate和endate,因此以下SQL应该可以工作:

          SELECT Customers.Firstname, Events.EventName, MAX(CustomerCheckins.CheckinDateTime)
            FROM CustomerCheckins 
      INNER JOIN Customers_Events 
              ON CustomerCheckins.CustomerID = Customers_Events.CustomerID 
 LEFT OUTER JOIN Customers 
              ON Customers_Events.CustomerID = Customers.CustomerID 
RIGHT OUTER JOIN Events 
              ON Customers_Events.EventID = Events.EventID
             AND events.StartDateTime <= CustomerCheckins.CheckinDateTime
             AND Events.EndDateTime > CustomerCheckins.CheckinDateTime
           WHERE (Customers_Events.CustomerID = 1887)
        GROUP BY Customers.Firstname, Events.EventName
选择Customers.Firstname、Events.EventName、MAX(CustomerCheckins.CheckinDateTime)
来自顾客切金斯
内部加入客户活动
在CustomerCheckins.CustomerID=Customers\u Events.CustomerID上
左外接客户
在客户上\u Events.CustomerID=Customers.CustomerID
右外部联接事件
在客户上\u Events.EventID=Events.EventID
和events.StartDateTime CustomerCheckins.CheckinDateTime
其中(Customers\u Events.CustomerID=1887)
按客户分组。Firstname,Events.EventName
请注意,如果用户在事件期间多次签入,则需要group by

checkindate的最小值或最大值的选择取决于您希望在事件期间显示第一次签入还是最后一次签入

旁注:

我对SQL Server查询优化器不是很熟悉,但它可能很难为这个查询创建一个好的执行计划。
如果您计划在实时系统中使用它,请确保在加载包含大量数据的表后对其进行测试。

问题在于您的数据库设计

您的数据模型不允许您将签入链接到特定事件

如果事件表包含startdate和enddate,则问题是可以解决的; 然后可以在联接中添加时间约束

编辑:

幸运的是,事件表中有startdate和endate,因此以下SQL应该可以工作:

          SELECT Customers.Firstname, Events.EventName, MAX(CustomerCheckins.CheckinDateTime)
            FROM CustomerCheckins 
      INNER JOIN Customers_Events 
              ON CustomerCheckins.CustomerID = Customers_Events.CustomerID 
 LEFT OUTER JOIN Customers 
              ON Customers_Events.CustomerID = Customers.CustomerID 
RIGHT OUTER JOIN Events 
              ON Customers_Events.EventID = Events.EventID
             AND events.StartDateTime <= CustomerCheckins.CheckinDateTime
             AND Events.EndDateTime > CustomerCheckins.CheckinDateTime
           WHERE (Customers_Events.CustomerID = 1887)
        GROUP BY Customers.Firstname, Events.EventName
选择Customers.Firstname、Events.EventName、MAX(CustomerCheckins.CheckinDateTime)
来自顾客切金斯
内部加入客户活动
在CustomerCheckins.CustomerID=Customers\u Events.CustomerID上
左外接客户
在客户上\u Events.CustomerID=Customers.CustomerID
右外部联接事件
在客户上\u Events.EventID=Events.EventID
和events.StartDateTime CustomerCheckins.CheckinDateTime
其中(Customers\u Events.CustomerID=1887)
按客户分组。Firstname,Events.EventName
请注意,如果用户在事件期间多次签入,则需要group by

checkindate的最小值或最大值的选择取决于您希望在事件期间显示第一次签入还是最后一次签入

旁注:

我对SQL Server查询优化器不是很熟悉,但它可能很难为这个查询创建一个好的执行计划。
如果您计划在实时系统中使用它,请确保在加载包含大量数据的表后对其进行测试。

问题在于您的数据库设计

您的数据模型不允许您将签入链接到特定事件

如果事件表包含startdate和enddate,则问题是可以解决的; 然后可以在联接中添加时间约束

编辑:

幸运的是,事件表中有startdate和endate,因此以下SQL应该可以工作:

          SELECT Customers.Firstname, Events.EventName, MAX(CustomerCheckins.CheckinDateTime)
            FROM CustomerCheckins 
      INNER JOIN Customers_Events 
              ON CustomerCheckins.CustomerID = Customers_Events.CustomerID 
 LEFT OUTER JOIN Customers 
              ON Customers_Events.CustomerID = Customers.CustomerID 
RIGHT OUTER JOIN Events 
              ON Customers_Events.EventID = Events.EventID
             AND events.StartDateTime <= CustomerCheckins.CheckinDateTime
             AND Events.EndDateTime > CustomerCheckins.CheckinDateTime
           WHERE (Customers_Events.CustomerID = 1887)
        GROUP BY Customers.Firstname, Events.EventName
选择Customers.Firstname、Events.EventName、MAX(CustomerCheckins.CheckinDateTime)
来自顾客切金斯
内部加入客户活动
在CustomerCheckins.CustomerID=Customers\u Events.CustomerID上
左外接客户
在客户上\u Events.CustomerID=Customers.CustomerID
右外部联接事件
在客户上\u Events.EventID=Events.EventID
和events.StartDateTime CustomerCheckins.CheckinDateTime
其中(Customers\u Events.CustomerID=1887)
按客户分组。Firstname,Events.EventName
请注意,如果用户在事件期间多次签入,则需要group by

checkindate的最小值或最大值的选择取决于您希望在事件期间显示第一次签入还是最后一次签入

旁注:

我对SQL Server查询优化器不是很熟悉,但它可能很难为这个查询创建一个好的执行计划。
如果您计划在实时系统中使用它,请确保在加载包含大量数据的表后对其进行测试。

问题在于您的数据库设计

您的数据模型不允许您将签入链接到特定事件

如果事件表包含startdate和enddate,则问题是可以解决的; 然后可以在联接中添加时间约束

编辑:

幸运的是,这次活动有开始和结束