【问题标题】:MySQL: Writing a complex queryMySQL:编写一个复杂的查询
【发布时间】:2014-12-25 02:19:56
【问题描述】:

我有 3 张桌子。这里我贴出它的数据库图。

您可以从这里下载数据库代码:https://www.dropbox.com/s/lk956afaxv147h0/testS.sql?dl=0

现在,使用这个数据库并使用“仅”mysql,我需要做以下工作。

1) 给定一个用户 ID,它应该得到一个该用户知道的所有单词的列表,按照他们学习的顺序排序。换句话说,最近学习的单词将位于列表的顶部。

2) 您将从“单词”表中获得包含该特定单词的所有文章的列表

3) 您将扫描此列表并返回表“Article”中包含最多 10 个“未知”单词的所有记录。换句话说,如果该文章包含超过 10 个未出现在用户词汇表中的单词(从表“Words_Learned”中提取),则将其从列表中排除。

4) 然后,您从第 1 步移至列表中的下一条记录。您重复相同的过程,除了跳过从第 3 步返回或作为第 3 步过滤过程的一部分排除的任何文章.

为了实现这个过程,我做了以下

SELECT `words_learned`.`idwords`,
Words.`idArticle`
FROM words_learned
INNER JOIN Words ON Words.idWords = Words_Learned.`idwords`
WHERE words_learned.userId = 1
ORDER BY Words_Learned.`order` DESC

在我的查询中,我已经涵盖了第 1 点和第 2 点。但是我需要做什么才能涵盖第 3 点和第 4 点?

【问题讨论】:

  • 3 可以通过一些 GROUP BY 和后聚合过滤(HAVING)来完成
  • @Mihai:感谢您的回复。你能用代码发布一个明确的答案吗?理解起来真的很有帮助。
  • 请注意,使用诸如COUNT 之类的关键字和/或诸如ORDER 之类的保留字作为表/列标识符是一种灾难。 COUNT 是一个特别奇怪的值,因为它不包含在 MySQL 的保留字列表中 - 但您只需尝试创建一个名为 COUNT 的表!
  • @Mihai:喂?请问可以提供代码示例吗?
  • 我看到了您的“示例的更多详细信息”,但它们描述的内容与原始任务完全不同。无论如何,您从哪里得到原始描述?听起来好像有一个程序使用不同的SQL语句和数组和循环,有人说:纯SQL应该可以,所以他们把原始程序的步骤写下来,现在必须转换为SQL(即沸腾它归结为:最终要选择什么)。但是,您现在添加的细节/示例令人困惑而不是帮助。是你在什么地方弄到的还是你自己编的?

标签: mysql sql database select join


【解决方案1】:

换句话说:显示所有不存在难读文章的学习单词。我没有按照建议一步一步地做。这是我的查询:

select *
from words_learned
where userid = 1
and not exists
(
  -- word being used in at least one article with too many unknown words
  select *
  from words
  where words.idwords = words_learned.idwords
  and words.idarticle in
  (
    -- articles with more then 10 unknown words
    select w.idarticle
    from words w
    left join words_learned l on l.idwords = w.idwords and l.userid = 1
    group by w.idarticle
    having count(*) - count(l.idwords) > 10
  )
)
order by `order` desc;

这是一个 SQL 小提琴:http://sqlfiddle.com/#!2/6de6a/4

【讨论】:

  • 感谢您的回复。但我认为您错过了这一点 - ` 换句话说,如果该文章包含超过 10 个未出现在用户词汇表中的单词(从表“Words_Learned”中提取) ),然后将其从列表中排除。`
  • 对不起,我认为这行得通!但是您能告诉我如何获取Articles 的详细信息吗?因为问题说You will scan this list and return all records from table Article
  • 我认为这些步骤描述了您需要做什么来找到不存在难以阅读的文章的单词。第一步是查找所有“最多包含 10 个生词”的文章。这并不意味着您必须展示这些文章,您只需要了解它们即可获得最终结果(或像我一样使用“换句话说,如果该文章包含超过 10 个单词......”的描述)。
  • 顺便说一句,我发现这些步骤有点误导,因为描述并没有简单地说明您要选择什么(这就是 SQL 的工作原理!)。它更确切地描述了您在使用编程语言时将遵循的一系列活动(将单词选择到数组中,获取第一条记录,选择单词的文章,......)。这使得编写 SQL 变得很困难(但可以很容易地用 C#、Java、Oracle 的 PL/SQL 或任何可用的编程语言编写程序)。
  • 我现在将发布更多详细的示例。请稍候。
【解决方案2】:

的答案 1) 给定一个用户 ID,它应该得到一个该用户知道的所有单词的列表,按照它们学习的顺序排序。换句话说,最近学习的单词将位于列表的顶部。

SELECT ar.content 
FROM article ar INNER JOIN words ws ON ar.idArticle = ws.idArticle 
  INNER JOIN words_learned wl ON wl.idwords = ws.idwords AND wl.userid = @givenID
ORDER BY ar.content DESC

这里 @givenID 提供了用户 ID,据我了解,内容将保持所学单词的价值

2) 您将从“单词”表中获得包含此特定单词的所有文章的列表

SELECT 
    * 
FROM 
    article ar 
INNER JOIN 
    words ws 
ON 
    ar.idArticle = ws.idArticle 
AND 
    ws.idwords is like '%pe%'

这将选择所有具有子字符串 pe 的单词,例如 sniper 等。您也可以通过将* 替换为ar.content 来仅选择文章内容

【讨论】:

  • 我的问题是关于第 3 点和第 4 点。我已经完成了您提供的答案。
猜你喜欢
  • 1970-01-01
  • 2015-07-13
  • 2015-01-28
  • 2021-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多