我已经处理这个 SQL 问题大约 2 天了,我怀疑我非常接近解决这个问题,但似乎无法找到一个完全有效的解决方案。
我正在尝试做的是在两个名为的表上进行选择性连接,application_info
这些表application_status
用于存储有关开放获取期刊文章资助请求的信息。
application_info
Application_ID
包含有关申请人的一般信息,并使用称为关键字段的自动索引字段。application_status
用于跟踪有关申请状态(已收到、正在审核、已资助、已拒绝、已撤回等)以及期刊文章状态(已提交、已接受、重新提交、已发表或已拒绝)的持续信息,并包含两者与状态文本和状态日期字段一起调用的Application_ID
字段和自动索引字段。Status_ID
因为我们想要保留应用程序、文章和资金状态更改的运行日志,我们不想application_status
用更新的值覆盖现有行,而是只想显示最近的状态值。因为一个应用程序最终会有不止一次的状态变化,这就需要对应用程序数据的状态数据的内部连接应用某种限制,以便每个应用程序 ID 只返回一行。
这是我在当前引发错误的查询中尝试执行的操作的示例:
-- simplified example
SELECT
application_info.*,
artstatus.Status_ID AS Article_Status_ID,
artstatus.Application_ID AS Article_Application_ID,
artstatus.Status_State_Date AS Article_Status_State_Date,
artstatus.Status_State_Text AS Article_Status_State_Text
FROM application_info
LEFT JOIN (
SELECT
Status_ID,
Application_ID,
Status_State_Text,
Status_State_Date,
Status_State_InitiatedBy,
Status_State_ChangebBy,
Status_State_Notes
FROM application_status
WHERE Status_State_Text LIKE 'Article Status%'
AND Application_ID = application_info.Application_ID -- how to pass the current application_info.Application_ID from the ON clause to here?
-- and Application_ID = 29 -- this would be an option for specific IDs, but not an option for getting a complete list of application IDs with status
-- GROUP BY Application_ID -- reduces the sub query to 1 row (Yeah!) but returns the first row encountered before the ORDER BY comes into play
ORDER BY Status_ID DESC
-- a GROUP BY after the ORDER BY might resolve the issue if we could do a sort first
LIMIT 1 -- only want to get the first (most recent) row, only works correctly if passing an Application_ID
) AS artstatus
ON application_info.Application_ID = artstatus.Application_ID
-- WHERE application_info.Application_ID = 29 -- need to get all IDs with statu values as well as for specific ID requests
;
消除AND Application_ID = application_info.Application_ID
子查询的 and 部分以及LIMIT
导致 select 工作的原因,但为给定应用程序 ID 的每个状态返回一行。我尝试过使用MIN
/MAX
运算符,但注意到它们application_status
在工作时会从表中返回不可预测的行。
我也尝试在ON
连接部分进行子选择,但不知道如何实现,因为最终结果总是需要返回一个Application_ID
(两者都Application_ID
可以Status_ID
返回和使用吗?)。
关于如何让它按我的意图工作的任何提示?这甚至可以做到吗?
进一步编辑:下面的工作查询。关键是将连接中的子查询更深一层,然后只返回一个状态 ID。
-- simplified example (now working)
SELECT
application_info.*,
artstatus.Status_ID AS Article_Status_ID,
artstatus.Application_ID AS Article_Application_ID,
artstatus.Status_State_Date AS Article_Status_State_Date,
artstatus.Status_State_Text AS Article_Status_State_Text
FROM application_info
LEFT JOIN (
SELECT
Status_ID,
Application_ID,
Status_State_Text,
Status_State_Date,
Status_State_InitiatedBy,
Status_State_ChangebBy,
Status_State_Notes
FROM application_status AS artstatus_int
WHERE
-- sub query moved one level deeper so current join Application_ID can be passed
-- order by and limit can now be used
Status_ID = (
SELECT status_ID FROM application_status WHERE Application_ID = artstatus_int.Application_ID
AND status_State_Text LIKE 'Article Status%'
ORDER BY Status_ID DESC
LIMIT 1
)
ORDER BY Application_ID, Status_ID DESC
-- no need for GROUP BY or LIMIT here because only one row is returned per Application_ID
) AS artstatus
ON application_info.Application_ID = artstatus.Application_ID
-- WHERE application_info.Application_ID = 29 -- works for specific application ID as well
-- more LEFT JOINS follow
;