私は、人が学んだすべての単語を取得し、それを自分自身に対して結合するサブクエリを作成したいと思うでしょう。単語GROUP_CONCATとカウントを一緒に使用します。だから与える:-
Octopus, NULL, 0
Dog, "Octopus", 1
Spoon, "Octopus,Dog", 2
したがって、サブクエリは次のようになります。-
SELECT sub0.idwords, GROUP_CONCAT(sub1.idwords) AS excl_words, COUNT(sub1.idwords) AS older_words_cnt
FROM words_learned sub0
LEFT OUTER JOIN words_learned sub1
ON sub0.userId = sub1.userId
AND sub0.order_learned < sub1.order_learned
WHERE sub0.userId = 1
GROUP BY sub0.idwords
与える
idwords excl_words older_words_cnt
1 NULL 0
2 1 1
3 1,2 2
次に、この結果を他のテーブルと結合し、メインのIDワードが一致するが、他のIDワードが見つからない記事を確認します。
このようなもの(ただし、テストデータがないためテストされていません):-
SELECT sub_words.idwords, words_inc.idArticle
(
SELECT sub0.idwords, SUBSTRING_INDEX(GROUP_CONCAT(sub1.idwords), ',', 10) AS excl_words, COUNT(sub1.idwords) AS older_words_cnt
FROM words_learned sub0
LEFT OUTER JOIN words_learned sub1
ON sub0.userId = sub1.userId
AND sub0.order_learned < sub1.order_learned
WHERE sub0.userId = 1
GROUP BY sub0.idwords
) sub_words
INNER JOIN words words_inc
ON sub_words.idwords = words_inc.idwords
LEFT OUTER JOIN words words_exc
ON words_inc.idArticle = words_exc.idArticle
AND FIND_IN_SET(words_exc.idwords, sub_words.excl_words)
WHERE words_exc.idwords IS NULL
ORDER BY older_words_cnt
LIMIT 100
編集-まだ学習されていない10語を超える記事を除外するように更新されました。
SELECT sub_words.idwords, words_inc.idArticle,
sub2.idArticle, sub2.count, sub2.content
FROM
(
SELECT sub0.idwords, GROUP_CONCAT(sub1.idwords) AS excl_words, COUNT(sub1.idwords) AS older_words_cnt
FROM words_learned sub0
LEFT OUTER JOIN words_learned sub1
ON sub0.userId = sub1.userId
AND sub0.order_learned < sub1.order_learned
WHERE sub0.userId = 1
GROUP BY sub0.idwords
) sub_words
INNER JOIN words words_inc
ON sub_words.idwords = words_inc.idwords
INNER JOIN
(
SELECT a.idArticle, a.count, a.content, SUM(IF(c.idwords_learned IS NULL, 1, 0)) AS unlearned_words_count
FROM Article a
INNER JOIN words b
ON a.idArticle = b.idArticle
LEFT OUTER JOIN words_learned c
ON b.idwords = c.idwords
AND c.userId = 1
GROUP BY a.idArticle, a.count, a.content
HAVING unlearned_words_count < 10
) sub2
ON words_inc.idArticle = sub2.idArticle
LEFT OUTER JOIN words words_exc
ON words_inc.idArticle = words_exc.idArticle
AND FIND_IN_SET(words_exc.idwords, sub_words.excl_words)
WHERE words_exc.idwords IS NULL
ORDER BY older_words_cnt
LIMIT 100
編集-上記のクエリにコメントを付けてみてください:-
これは列を選択するだけです
SELECT sub_words.idwords, words_inc.idArticle,
sub2.idArticle, sub2.count, sub2.content
FROM
このサブクエリは、学習した各単語と、order_learnedが大きい単語のコンマ区切りのリストを取得します。これは特定のユーザーID用です
(
SELECT sub0.idwords, GROUP_CONCAT(sub1.idwords) AS excl_words, COUNT(sub1.idwords) AS older_words_cnt
FROM words_learned sub0
LEFT OUTER JOIN words_learned sub1
ON sub0.userId = sub1.userId
AND sub0.order_learned < sub1.order_learned
WHERE sub0.userId = 1
GROUP BY sub0.idwords
) sub_words
これは、単語(つまり、上記のサブクエリから学習した単語)が使用されている記事を取得するためだけのものです
INNER JOIN words words_inc
ON sub_words.idwords = words_inc.idwords
このサブクエリは、特定のユーザーによってまだ学習されていない、単語が10語未満の記事を取得します。
INNER JOIN
(
SELECT a.idArticle, a.count, a.content, SUM(IF(c.idwords_learned IS NULL, 1, 0)) AS unlearned_words_count
FROM Article a
INNER JOIN words b
ON a.idArticle = b.idArticle
LEFT OUTER JOIN words_learned c
ON b.idwords = c.idwords
AND c.userId = 1
GROUP BY a.idArticle, a.count, a.content
HAVING unlearned_words_count < 10
) sub2
ON words_inc.idArticle = sub2.idArticle
この結合は、最初のサブクエリからコンマで区切られたリストに単語がある記事(つまり、order_learnedが大きい単語)を検索するためのものです。見つかった単語を除外したいので、これはLEFT OUTER JOINとして実行されます(これは、WHERE句でNULLをチェックすることによって実行されます)
LEFT OUTER JOIN words words_exc
ON words_inc.idArticle = words_exc.idArticle
AND FIND_IN_SET(words_exc.idwords, sub_words.excl_words)
WHERE words_exc.idwords IS NULL
ORDER BY older_words_cnt
LIMIT 100