sql >> データベース >  >> RDS >> Mysql

複雑なMySQLクエリの記述

    私は、人が学んだすべての単語を取得し、それを自分自身に対して結合するサブクエリを作成したいと思うでしょう。単語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
    


    1. OPENJSON、JSON_QUERY、およびJSON_VALUE(SQL Server)を使用するときに特殊文字を含むJSONキーを参照する方法

    2. PHP:単一のクエリで複数のMySQLフィールドを更新する

    3. SQLデータベースからphp/htmlテーブルにデータを表示します

    4. MySQLで2つのテーブルを比較する方法