MYSQL从多个表中选择多个

时间:2017-06-10 10:36:37

标签: mysql join

我有X表,我想要一个查询来获取我想要的所有数据。我想要这个方法的原因是我的数据库中有超过10.000个记录,所以我必须只使用1个查询,因为如果我使用3-4个查询和10个数据,则需要很长时间才能执行服务器

所以表:

** book_info **    
bookId   status        title
------   ------        -----
101      available     How to cook
102      available     IT tips and tricks
103      unavailable   How to use your calc
etc...


** book_writers **    
bookId   writer
------   ------
101      Tom
102      Mike
103      Mike
etc...


** book_log **    
bookId   action   client   date
------   ------   ------   ----
103      loan     Fred     2017-6-10
102      loan     Anna     2017-6-8
101      return   Anita    2017-5-3
101      loan     Anita    2017-2-2
etc...

我想要的只有一个查询:

bookId   status      title                writer   lastLoan   lastReturn
------   ------      -----                ------   --------   ----------
101      available   How to cook          Tom      2017-2-2   2017-5-3
102      available   IT tips and tricks   Mike     2017-6-8   -
etc...

我是通过使用JOIN和UNION来尝试的,但我做不到。

更新

因为我从你们那里得到了很好的解决方案,我终于构建了我所寻找的查询。但我不能做的一件事是在“子”连接查询中使用“父”查询变量。

所以我有一张包含书籍内容的表格:

** book_content **    
bookId   content
------   -------
101      Lorem ipsum dolor sit amet, consectetur...
102      Donec ut lacus non odio blandit molestie
103      Interdum et malesuada fames ac ante ipsum...
etc...

我试图像

一样查询它
select
  bi.bookId
  bd.content
from
  books_info as bi
left outer join
(
  select
    bookId
    content
  from
    book_content
  where
    bookId = bi.bookId
) bd on bi.bookId = bd.bookId

但是SQL在连接选择中说#1054 - Unknown column 'bi.bookId' in 'where clause'。如何在子连接查询中使用bi.bookId

3 个答案:

答案 0 :(得分:0)

您可以使用两次book_log

来使用内部和左侧连接
select i.bookId, i.status, i.title, w.writer, max(l1.date) lastLoan,  max(l2.date) lastReturn
from book_info as i
inner join book_writers w on i.bookId = w.bookId
inner join book_log l1 on i.book_id = l1.book_id and l1.action ='load'
left join  book_log l2 on i.book_id = l2.book_id and l2.action ='return'
group by i.bookId, i.status, i.title

和(正如Tuncay在下面的评论中所建议的那样)

如果有多个authot

,请使用group_concat
select i.bookId, i.status, i.title, group_concat(w.writer), max(l1.date) lastLoan,  max(l2.date) lastReturn
from book_info as i
inner join book_writers w on i.bookId = w.bookId
inner join book_log l1 on i.book_id = l1.book_id and l1.action ='load'
left join  book_log l2 on i.book_id = l2.book_id and l2.action ='return'
group by i.bookId, i.status, i.title

答案 1 :(得分:0)

尝试此查询希望它能正常工作。

SELECT bi.bookId,status,title,writer,bl.lastLoan,
           bl.lastReturn,bl.totalLoan,bl.totalReturn
from book_info bi
left outer join book_writers as bw on bi.bookId = bw.bookId
left outer join(
SELECT 
bookId,
COUNT(CASE WHEN action = 'loan' THEN action END) AS totalLoan,
COUNT(CASE WHEN action = 'return' THEN action END) AS totalReturn,
 CASE
        WHEN action = 'loan' THEN date
END AS lastLoan,
    MAX(CASE
        WHEN action = 'return' THEN date
END) AS lastReturn

FROM book_log
group by bookId

)  bl on bi.bookId = bl.bookId
group by bi.bookId

如果你有书籍内容,它将显示,否则它将显示为空。

select
  bi.bookId
  bd.content
from
  books_info as bi
left join book_content as bd on bi.bookId = bd.bookId
group by bi.bookId

enter image description here

编辑:为图书内容添加了第二个查询。

答案 2 :(得分:0)

这是我的看法。与scaisEdge基本相同,但更详细一点。我为它创建了一个sqlfiddle

select
  i.`bookId`,
  i.`status`,
  i.`title`,
  group_concat(w.`writer`) as writers,
  coalesce(max(ll.`date`), '') as lastLoan,
  coalesce(max(lr.`date`), '') as lastReturn
from
  book_info i
left join
  book_writers w on w.bookId=i.bookId
left join
  book_log ll on (ll.bookId=i.bookId) and (ll.`action`='loan')
left join
  book_log lr on (lr.bookId=i.bookId) and (lr.`action`='return') and (lr.`date` >= ll.`date`)
group by
  w.bookId