MYSQL多表多选

Posted

技术标签:

【中文标题】MYSQL多表多选【英文标题】:MYSQL multiple select from multiple tables 【发布时间】:2017-11-12 07:54:25 【问题描述】:

我有 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

【问题讨论】:

请显示您尝试的查询。 只是在 phpMyadmin 中尝试了几次。 看起来像一个简单的查询,有几个连接,一个 group_concat 用于作者,一个子选择用于贷款/归还给我。 我已经发布了查询,请检查我执行的查询它对我有用。 【参考方案1】:

您可以使用两次 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

【讨论】:

我建议对作者进行分组(书籍可能有多个作者,即该表中的 bookId 可能不是唯一的)。同样加入 book_log 两次可能不一定会返回贷款并从同一(最后)行返回,所以我建议在加入时使用子查询。 你能写吗? .. 也用组 concat 回答 uodated 并添加缺少的组 谢谢!无论如何,它说“行动”是模棱两可的。 是拼写错误“t1”而不是“l1”吗?【参考方案2】:

这是我的看法。与 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

【讨论】:

它运作良好,但是您能否添加另一个字段,例如“totalLoans”,它计算有多少贷款有书籍?我更新了小提琴:sqlfiddle.com/#!9/6aca38/3 如果我在日志中添加更多记录,它还会在“所有者”处重复列【参考方案3】:

试试这个查询,希望它能起作用。

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

如果您有书籍内容,它将显示,否则将显示 null。

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

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

【讨论】:

添加了totalLoans、totalReturn。确保它在单个查询中执行更多操作,这样会很冗长且耗时。 我还在测试中。什么是“THEN date END”方法? THEN END 是关键字,“date”是您要显示日期的列名 我明白了。我昨天测试了很多,它似乎有效,非常感谢你和大家!但还有一件事,我更新了帖子。 是的,这就是我尝试过的,但似乎我的 mysql 每次都超时。卡在“加载”页面,我必须重新启动它。无论如何,我正在处理约 300.000 条记录。

以上是关于MYSQL多表多选的主要内容,如果未能解决你的问题,请参考以下文章

Mysql单表多表查询

mysql单表多表查询

linux12 -MYSQL数据库 -->04 数据表单表多表查询--02

mysql搜索多表多字段模糊查询

Linq中的group by多表多字段

单表多表操作 联表查询