0

我有四张桌子

  • Customers- PK:CustomerID
  • Events- PK:EventID
  • Customers_Events- 包含两个 FK 的连接表CustomerIDEventID
  • Customer_Checkins- 包含一个时间戳列 ( CheckinDateTime) 和一个 FK 引用CustomerID

我想要这样的输出

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

每条有效记录返回 3 次

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

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)

我真的很感激一些帮助来解决这个问题。我觉得我已经尝试了剧本中的每一种组合。

4

2 回答 2

2

你应该使用grouping而不是distinct

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
于 2013-10-18T10:28:21.600 回答
1

问题在于您的数据库设计。

您的数据模型不允许您将签到与特定事件相关联。

如果您的事件表包含开始日期和结束日期,则问题是可以解决的;然后你可以在你的加入中添加时间限制。

编辑:

幸运的是,事件表中有一个开始日期和结束日期,所以下面的 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

请注意,您需要 group by,以防用户在活动期间签入超过一次。

checkindate 的 MIN 或 MAX 选择取决于您是要显示事件期间的第一个签到还是最后一个签到。

边注:

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

于 2013-10-18T10:32:57.397 回答