我需要在MySQL中使用CROSS APPLY(EC2 RDS MySQL实例)。 看起来MySQL并没有识别出CROSS APPLY语法。有人能帮帮我吗?
这是查询。
function noFalsy(arr) {
var none=function(val){
switch (val){
case false:
case null:
case "":
case 0:
case undefined:
case NaN:
return false;
default:
return true;
}
},
ans=[];
ans=arr.filter(none);
return ans;
}
答案 0 :(得分:15)
您最近的 直接 近似值是一个以相关子查询作为谓词的联接。
SELECT
ORD.ID
,ORD.NAME
,ORD.DATE
,ORD_HISTORY.VALUE
FROM
ORD
INNER JOIN
ORD_HISTORY
ON ORD_HISTORY.<PRIMARY_KEY>
=
(SELECT ORD_HISTORY.<PRIMARY_KEY>
FROM ORD_HISTORY
WHERE ORD.ID = ORD_HISTORY.ID
AND ORD.DATE <= ORD_HISTORY.DATE
ORDER BY ORD_HISTORY.DATE DESC
LIMIT 1
)
但是,在您的情况下,您只需要目标表中的一个字段。这意味着您可以直接在SELECT语句中使用相关的子查询。
SELECT
ORD.ID
,ORD.NAME
,ORD.DATE
,(SELECT ORD_HISTORY.VALUE
FROM ORD_HISTORY
WHERE ORD.ID = ORD_HISTORY.ID
AND ORD.DATE <= ORD_HISTORY.DATE
ORDER BY ORD_HISTORY.DATE DESC
LIMIT 1
) AS VALUE
FROM
ORD
答案 1 :(得分:2)
从MySQL 8.0.14开始,您可以使用LATERAL
:
现在派生表之前可以使用LATERAL关键字,以指定允许它引用(取决于)同一FROM子句中先前表的列。用LATERAL指定的派生表只有在可能会发生FROM子句,无论是在表的列表使用逗号或在加入说明书中分开(JOIN,INNER JOIN,CROSS JOIN,LEFT [OUTER] JOIN,或RIGHT [OUTER] JOIN)。横向派生表使某些SQL操作可能无法通过非横向派生表完成,或者需要效率较低的解决方法
CROSS APPLY () <=> ,LATERAL ()
OUTER APPLY () <=> LEFT JOIN LATERAL () ON 1=1
Support for LATERAL derived tables added to MySQL 8.0.14
在这种情况下:
SELECT ORD.ID
,ORD.NAME
,ORD.DATE
,ORD_HIST.VALUE
FROM ORD,
LATERAL (
SELECT ORD_HISTORY.VALUE
FROM ORD_HISTORY
WHERE ORD.ID = ORD_HISTORY.ID
AND ORD.DATE <= ORD_HISTORY.DATE
ORDER BY ORD_HISTORY.DATE DESC
LIMIT 1
) ORD_HIST
答案 2 :(得分:1)
基于@lujas szozda答案:
对于交叉申请:
SELECT ORD.ID
,ORD.NAME
,ORD.DATE
,ORD_HIST.VALUE
FROM ORD JOIN
LATERAL (
SELECT ORD_HISTORY.VALUE
FROM ORD_HISTORY
WHERE ORD.ID = ORD_HISTORY.ID
AND ORD.DATE <= ORD_HISTORY.DATE
ORDER BY ORD_HISTORY.DATE DESC
LIMIT 1
) ORD_HIST ON 1=1
/* ON 1=1 is just a trick to join to whatever the LATERAL returns */
对于外部申请:
SELECT ORD.ID
,ORD.NAME
,ORD.DATE
,ORD_HIST.VALUE
FROM ORD LEFT JOIN
LATERAL (
SELECT ORD_HISTORY.VALUE
FROM ORD_HISTORY
WHERE ORD.ID = ORD_HISTORY.ID
AND ORD.DATE <= ORD_HISTORY.DATE
ORDER BY ORD_HISTORY.DATE DESC
LIMIT 1
) ORD_HIST ON 1=1
/* ON 1=1 is just a trick to join to whatever the LATERAL returns */