2014-11-02 51 views
0

我有三个表,libraryitems,副本和贷款。MySQL的子选择需要

A libraryitem hasMany copies,副本hasMany贷款。

我试图获取只有一个副本最新贷款条目;以下查询返回给定副本的全部贷款。

SELECT 
libraryitems.title, 
copies.id, 
copies.qruuid, 
loans.id AS loanid, 
loans.status, 
loans.byname, 
loans.byemail, 
loans.createdAt 
FROM copies 
INNER JOIN libraryitems ON copies.libraryitemid = libraryitems.id AND libraryitems.deletedAt IS NULL 
LEFT OUTER JOIN loans ON copies.id = loans.copyid 
WHERE copies.libraryitemid = 1 
ORDER BY copies.id ASC, loans.createdAt DESC 

我知道在这里需要一些子选择的描述,但努力获得正确的语法。我怎样才能为每个不同的副本返回最新的,即MAX(loans.createdAt)行?只需使用group by copy.id返回最早的条目,而不是最新的条目。

图片下面的例子: enter image description here

+1

(如穆赫辛已经证明)子查询是不严格necesssary - 但它往往会更快! – Strawberry 2014-11-02 12:43:14

回答

1
子查询

,获得最大的创建时间的贷款,即最近一次入境,并与贷款结合回去取其他细节。

SELECT 
T.title, 
T.id, 
T.qruuid, 
loans.id AS loanid, 
loans.status, 
loans.byname, 
loans.byemail, 
loans.createdAt 
FROM 
(
    SELECT C.id, C.qruuid, L.title, MAX(LN.createdAt) as maxCreatedTime 
    FROM Copies C 
    INNER JOIN libraryitems L ON C.libraryitemid = L.id 
    AND L.deletedAt IS NULL 
    LEFT OUTER JOIN loans LN ON C.id = LN.copyid 
    GROUP BY C.id, C.qruuid, L.title) T 
JOIN loans ON T.id = loans.copyid 
AND T.maxCreatedTime = loans.createdAt 
+0

我得到[Err] 1146 - 表'qweylibrary.ln'与此不存在? – Neokoenig 2014-11-02 13:00:54

+0

@Neokoenig,别名在选择一列时错过了,你现在可以试试吗? – radar 2014-11-02 13:04:29

+0

完美!非常感谢 - 正在做我的头:) – Neokoenig 2014-11-02 13:07:39

1

自左加入贷款表会给你一份最新的贷款,你可能join查询到其他表来获取所需的输出。

select * from loans A 
left outer join loans B 
on A.copyid = B.copyid and A.createdAt < B.createdAt 
where B.createdAt is null; 
+0

Thankyou,这也是v得心应手! – Neokoenig 2014-11-02 13:42:24

0

这是您的查询,只需一个简单的修改 - 表别名,使其更清晰。

SELECT li.title, c.id, c.qruuid, 
     l.id AS loanid, l.status, l.byname, l.byemail, l.createdAt 
FROM copies c INNER JOIN 
    libraryitems li 
    ON c.libraryitemid = li.id AND 
     li.deletedAt IS NULL LEFT JOIN 
    loans l 
    ON c.id = l.copyid 
WHERE c.libraryitemid = 1 
ORDER BY c.id ASC, l.createdAt DESC ; 

将此作为开始,让我们考虑一下你需要什么。您需要每个c.id的最新日期为createdAt的负载。您可以使用子查询得到这个信息:现在

select l.copyid, max(createdAt) 
from loans 
group by l.copyId 

,你只需要回来参加这个信息:

SELECT li.title, c.id, c.qruuid, 
     l.id AS loanid, l.status, l.byname, l.byemail, l.createdAt 
FROM copies c INNER JOIN 
    libraryitems li 
    ON c.libraryitemid = li.id AND 
     li.deletedAt IS NULL LEFT JOIN 
    loans l 
    ON c.id = l.copyid LEFT JOIN 
    (SELECT l.copyid, max(l.createdAt) as maxca 
     FROM loans 
     GROUP BY l.copyid 
    ) lmax 
    ON l.copyId = lmax.copyId and l.createdAt = lmax.maxca 
WHERE c.libraryitemid = 1 
ORDER BY c.id ASC, l.createdAt DESC ; 

这应该给你最新的记录。而且,使用left join应该保留所有副本,即使那些从来没有出租过的副本。