【问题标题】:SQLite: search keywords' table with separate rows and joining multiple tablesSQLite:用单独的行搜索关键字的表并连接多个表
【发布时间】:2018-03-25 17:41:55
【问题描述】:

我有三个 SQLite 表,一个 products 表,一个 keywords_products 表和一个 keywords 表。

CREATE TABLE products (
    product_rec_id  INTEGER  PRIMARY KEY  NOT NULL,
    name            VARCHAR (100)  NOT NULL
);

CREATE TABLE keywords_products (
    keyword_rec_id INTEGER NOT NULL,
    product_rec_id INTEGER NOT NULL
);

CREATE TABLE keywords (
    keyword_rec_id INTEGER  PRIMARY KEY  NOT NULL,
    keyword        VARCHAR (50)  NOT NULL  UNIQUE
);

keywords_products 表保存产品的记录 ID 和关键字的记录 ID。每个产品都可以在 keywords 表中分配多个关键字。

keyword 表如下所示:

keyword_rec_id  keyword
--------------  -----------
60              melee
43              scifi
87              water

keywords_products 表如下所示(一个关键字可以分配给多个产品):

keyword_rec_id  product_rec_id
--------------  --------------
43              1
60              1
43              2
87              3

products 表如下所示:

product_rec_id  name
--------------  --------------
1               Scifi Melee Weapons
2               Scifi Ray Weapon
3               Lake House

很长一段时间我一直在使用这个 SQL 命令,但是我只是注意到对于 AND 操作它显然不起作用,因为所有关键字都在单独的行中。

SELECT
  products.product_rec_id,
  keywords.keyword
FROM
  products
  LEFT OUTER JOIN keywords_products ON
    products.product_rec_id = keywords_products.product_rec_id
  LEFT OUTER JOIN keywords ON
    keywords_products.keyword_rec_id = keywords.keyword_rec_id
WHERE
  (keywords.keyword LIKE '%scifi%' OR
    keywords.keyword LIKE '%melee%')

有时我希望能够检索与输入的所有关键字 (AND) 或仅匹配一个关键字 (OR) 的产品(OR 操作是我现在唯一能做的)。

【问题讨论】:

    标签: sqlite outer-join


    【解决方案1】:

    你可以使用HAVING:

    SELECT  products.product_rec_id, COUNT(DISTINCT keywords.keyword) AS cnt
    FROM  products
    LEFT OUTER JOIN keywords_products ON
        products.product_rec_id = keywords_products.product_rec_id
    LEFT OUTER JOIN keywords ON
        keywords_products.keyword_rec_id = keywords.keyword_rec_id
    WHERE  (keywords.keyword LIKE '%scifi%' OR   keywords.keyword LIKE '%melee%')
    GROUP BY products.product_rec_id
    HAVING SUM(CASE WHEN keywords.keyword LIKE '%scifi%' THEN 1 ELSE 0 END)>0
      AND SUM(CASE WHEN keywords.keyword LIKE '%melee%' THEN 1 ELSE 0 END) > 0;
    

    编辑:

    同时获取两者(如果在同一行):

    SELECT  products.product_rec_id,keywords.keyword
    FROM  products
    LEFT OUTER JOIN keywords_products ON
        products.product_rec_id = keywords_products.product_rec_id
    LEFT OUTER JOIN keywords ON
        keywords_products.keyword_rec_id = keywords.keyword_rec_id
    WHERE  keywords.keyword LIKE '%scifi%melee%'
       OR keywords.keyword LIKE '%melee%scifi%';
    

    【讨论】:

    • HAVING 的行为方式与 WHERE 相同,OR 有效,但 AND 无效。
    • @nDelphi 不,它的行为方式不同。 WHERE 适用于行级,HAVING 适用于行组
    • 在这种情况下,它们返回相同的结果。此外,这永远不会起作用:keywords.keyword LIKE '%scifi%melee%' 因为关键字位于不同的行中。我编辑了我的问题以使其更清楚。
    • 它确实有效,罪魁祸首是 GROUP BY products.product_rec_id,keywords.keyword 中的“,keywords.keyword”。谢谢您的帮助。我很感激。
    • 我想我做到了。我有这个没有 HAVING 的代码。在这种情况下,TRows 和 84(Kwords2)的结果应该是 310,这就是我得到的结果。这对您来说是否正确?从产品....
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-17
    • 1970-01-01
    • 1970-01-01
    • 2014-06-22
    • 1970-01-01
    • 2011-09-28
    相关资源
    最近更新 更多