Writing a Complex MySQL Query

前端 未结 3 916
误落风尘
误落风尘 2021-01-17 06:26

Note: you can find my previous question and its answer here - MySQL: Writing a complex query


I have 3 tables.

Table Words_Learned contains

3条回答
  •  伪装坚强ぢ
    2021-01-17 06:59

    I've read that question again and notice it is much more complicated.

    First of all you want to show words. And whether you show a word depends on that word and all before-learned words (and the articles they appear in).

    So with these words learned:

    word      order
    Octopus   3
    Dog       2
    Spoon     1 (i.e.first learned)
    

    And these articles:

    article  contains Octopus   contains Dog   contains spoon   unknown words
    A             yes               yes             yes              5
    B             yes               yes             no              11
    C             yes               no              yes             15
    D             no                yes             yes              2
    E             no                yes             no               0
    F             no                no              yes              8
    G             no                no              no               3
    H             no                no              no              20
    

    You ...

    • check "Octupus" and dismiss it because of article B or C.
    • check "Dog" and keep it, because articles D and E are okay and B must be ignored (as it contains "Octopus").
    • check "Spoon" and keep it, article F is okay and C must be ignored (as it contains "Octopus").

    So you show "Dog" and "Spoon" and not "Octopus". And if there were not only two matches, but thousand, you would show the first 100 and then stop.

    Given this algorithm, we can conclude:

    • As long as too few word were learned, no results will be shown at all.
    • At some point enough words will be learned to find articles with less than 11 unknown words. The last-learned words will probably not be shown (as "Octopus" in the example), because there are still many articles with too many unknown words. But earlier words will be shown (because the last-learned words filter away the hard-to-read articles).
    • Then some day most of the words will be learned. Then it is the last-learned words that will be shown.

    The query:

    select idwords
    from words_learned
    where userid = 123
    and not exists
    (
      select w.idarticle
      from words w
      left join words_learned l on l.idwords = w.idwords and l.userid = 123
      group by w.idarticle
      having sum(l.idwords is null) > 10 and max(l.`order`) = words_learned.`order`
    )
    order by `order` desc
    limit 100;
    

    Here is an SQL fiddle: http://sqlfiddle.com/#!2/19bf8/1.

提交回复
热议问题