我一直在处理这个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
和子查询的一部分以及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
;
答案 0 :(得分:2)
在from子句中不能有相关的子查询。
请尝试这个想法:
select <whatever>
from (select a.*,
(select max(status_id) as maxstatusid
from application_status aps
where aps.application_id = a.application_id
) as maxstatusid
from application
) left outer join
application_status aps
on aps.status_id = a.maxstatusid
. . .
也就是说,将相关子查询放在select子句中以获取最新状态。然后将其加入状态表以获取其他信息。并使用其他详细信息完成查询。
您似乎非常擅长自己的SQL技能,所以似乎没有必要为您重写整个查询。