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
-PK:Events
EventID
-包含两个FK的联接表Customers\u Events
和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,则问题是可以解决的; 然后可以在联接中添加时间约束 编辑: 幸运的是,这次活动有开始和结束