【问题标题】:where statement execute before inner joinwhere 语句在内部连接之前执行
【发布时间】:2018-07-22 12:39:39
【问题描述】:

我正在尝试使用小于 4 的 sysAddress 来获取每个结果的第一个实例。但是我的语句目前在应用 where sysAddress

我应该以不同的方式嵌套它吗?我不想创建额外的表连接层。这可能吗?我对我找到的所有答案有点迷茫。

    SELECT
  tblHistoryObject.info,
  tblHistory.actionTime,
  tblHistoryUser.userID,
  tblHistoryUser.firstName,
  tblHistoryUser.surname,
  tblHistory.eventID,
  tblHistoryObject.objectID,
  tblHistorySystem.sysAddress

FROM tblHistoryObject


JOIN tblHistory
  ON (tblHistory.historyObjectID = tblHistoryObject.historyObjectID)
JOIN tblHistorySystem
  ON (tblHistory.historySystemID = tblHistorySystem.historySystemID)
JOIN tblHistoryUser
  ON (tblHistory.historyUserID = tblHistoryUser.historyUserID)


INNER JOIN (SELECT
  MIN(actionTime) AS recent_date,
  historyObjectID
FROM tblHistory
GROUP BY historyObjectID) AS t2
  ON t2.historyObjectID = tblHistoryObject.historyObjectID
  AND tblHistory.actionTime = t2.recent_date


WHERE sysAddress < 4
ORDER BY actionTime ASC

【问题讨论】:

  • 看看SELECT (Transact-SQL),特别是关于逻辑处理的部分。您会注意到WHERE 是要处理的第四个逻辑部分,而ONJOIN 分别是第二个和第三个。如果您需要在 JOIN 之前执行当前位于 WHERE 中的内容,请将其移至 ON 子句中。
  • 这个查询中JoinInner join有什么区别,并且没有aggergate,在select查询中,在这个实例中看不到分组的原因
  • @BHouse,GROUP BY 上方有 MIN 3 行。 (格式差的 SQL 更难阅读……)
  • 建议您包含一些示例数据(输入和预期结果),以展示您正在处理的内容以及您想要完成的内容。
  • 实际上很难告诉确切你想要什么,因为你没有给出任何实际的例子。所以我们不得不从你的描述中推断出它(不幸的是,描述性不是很好;一张图片值一千字,所以给我们展示一些示例数据和你想要的结果)。我的第一个推断是,您只希望tblHistoryObject 中每行的结果中有一行?

标签: sql sql-server select inner-join


【解决方案1】:
WITH
  all_action_times AS
(
    SELECT
      tblHistoryObject.info,
      tblHistory.actionTime,
      tblHistoryUser.userID,
      tblHistoryUser.firstName,
      tblHistoryUser.surname,
      tblHistory.eventID,
      tblHistoryObject.objectID,
      tblHistorySystem.sysAddress,
      ROW_NUMBER() OVER (PARTITION BY tblHistoryObject.historyObjectID
                             ORDER BY tblHistory.actionTime
                        )
                          AS historyObjectID_SeqByActionTime
    FROM
      tblHistoryObject
    INNER JOIN
      tblHistory
        ON tblHistory.historyObjectID = tblHistoryObject.historyObjectID
    INNER JOIN
      tblHistorySystem
        ON tblHistory.historySystemID = tblHistorySystem.historySystemID
    INNER JOIN
      tblHistoryUser
        ON tblHistory.historyUserID = tblHistoryUser.historyUserID
    WHERE
      tblHistorySystem.sysAddress < 4
)
SELECT
  *
FROM
  all_action_times
WHERE
  historyObjectID_SeqByActionTime = 1
ORDER BY
  actionTime ASC

这与您的原始查询完全一样,无需尝试按 action_time 过滤。

然后它附加一个新列,使用ROW_NUMBER()1 为每个tblHistoryObject.historyObjectID 生成序列。 那么只取该序列值为1的行(按historyObjectID排序的第一行,按action_time顺序排序时) em>。

【讨论】:

  • 这是完美的。正是我想要做的。谢谢你。帮了大忙。
猜你喜欢
  • 1970-01-01
  • 2019-11-08
  • 2016-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-14
  • 2011-12-02
相关资源
最近更新 更多