繁体   English   中英

SQLite 中的子选择

[英]Sub-selects in SQLite

问题

我最近正在完成一项技术测试,这需要我执行一个相当复杂的SQL 查询,我想在收到任何反馈之前知道我给出的答案是否正确,以及如何改进.

这是我对问题的解释

假设我们有一个卖帽子的网站,我们想为它建立一个数据库。 每种帽子都有尺寸、价格等。每种帽子也可以分为无、一个或多个类别,这些类别本身可以是公共的或私有的。

请执行下列操作:

  1. 编写伪 SQL 代码,创建上述 model 所需的表。
  2. 编写一个查询,该查询将返回属于至少 5 个公共类别的帽子类型的记录。

我的尝试

由于我的大部分经验是 SQLite,我从 SQLite 的角度解决了这个问题,我在我的回答中的评论中写了这个。

关于上面的第 (1) 点,我创建了三个表: HatCategoryBelongsToCategory ,最后一个是前两个的连接表。 publicCategory表的一列, INTEGER类型:0 为假,1 为真。

至于第(2)点,这是我的查询:

SELECT *
FROM Hat
WHERE
    (SELECT COUNT(*)
     FROM BelongsToCategory
         JOIN Category ON Category.code = BelongsToCategory.category
         WHERE (BelongsToCategory.hat = Hat.code) AND (Category.public = 1))
    >= 5

测试我的尝试

我以以下方式测试了我的尝试:

  • 我制作了自己的.db 文件。
  • 我使用SQLite 的数据库浏览器打开了该文件。
  • 如上所述,我创建了我的表。
  • 我将数据添加到这些表中,如下所示:
    • 我在Hat表中添加了三个新记录:hat1、hat2 和 hat3。
    • 我在Category表中添加了 6 条新记录:cat1 到 cat6,其中 cat1 到 cat5 是公共的,而 cat6 是私有的。
    • 我在BelongsToCategory表中添加了记录,因此 hat1 属于类别 cat1 到 cat5,hat2 只属于 cat1,而 hat3 属于类别 cat1 到 cat4 以及 cat6。
  • 我运行了上面的 SQL 代码。

当我运行上面的 SQL 代码时,它返回了 hat1 的记录。 任务完成。 没那么快..,当我试着玩一下,把 5 换成 4,或者 3、2 等等,我一直在获得 hat1 的记录。 仅此而已,只有当我到达 1 时,hat3 才开始弹出。 我从来没有见过hat2。

这是怎么回事? 我的查询有问题吗? 或者这是 SQLite 浏览器中的错误?

我想知道的

  • 上面的 SQL 查询是否正确?
  • 如何改进?

我不认为您的查询有任何问题(我已经对其进行了测试,并且可以按预期工作)。 因此,我相信您可能没有按预期插入数据。

如果您将计数子查询作为附加列添加到主查询并使用 >= 0 您可以查看计数并查看计数情况

例如:-

SELECT *, (SELECT COUNT(*)
     FROM BelongsToCategory
         JOIN Category ON Category.code = BelongsToCategory.category
         WHERE (BelongsToCategory.hat = Hat.code) AND (Category.public = true)) AS cat_count
FROM Hat
WHERE
    (SELECT COUNT(*)
     FROM BelongsToCategory
         JOIN Category ON Category.code = BelongsToCategory.category
         WHERE (BelongsToCategory.hat = Hat.code) AND (Category.public = true))
    >= 0
;

以下用于测试上述内容:-

PRAGMA foreign_keys = ON;
DROP TABLE IF EXISTS BelongsToCategory;
DROP TABLE IF EXISTS Hat;
DROP TABLE IF EXISTS Category;
CREATE TABLE IF NOT EXISTS Hat (code INTEGER PRIMARY KEY, hattype TEXT, hatprice REAL, hatsize REAL, hatetc TEXT);
CREATE TABLE IF NOT EXISTS Category (code INTEGER PRIMARY KEY, category TEXT, public INTEGER);
CREATE TABLE IF NOT EXISTS BelongsToCategory (
    hat INTEGER REFERENCES Hat(code) ON DELETE CASCADE ON UPDATE CASCADE
    , category INTEGER REFERENCES Category(code) ON DELETE CASCADE ON UPDATE CASCADE
    , PRIMARY KEY(hat,category)
    )   
;

INSERT INTO Category VALUES(1,'cat1',true),(2,'cat2',true),(3,'cat3',true),(4,'cat4',true),(5,'cat5',true),(6,'cat6',false);
INSERT INTO Hat VALUES(1,'hat1',100,7,'other'),(2,'hat2',90,6,'other'),(3,'hat3',95,5,'other'),(4,'hat4',110,8,'other'),(5,'hat5',120,8,'other');
INSERT INTO BelongsToCategory VALUES
    (1,1),(1,2),(1,3),(1,4),(1,5),(1,6)
    ,(2,1)
    ,(3,1),(3,2),(3,3),(3,4)
    ,(5,6),(5,1)
;

SELECT *, (SELECT COUNT(*)
     FROM BelongsToCategory
         JOIN Category ON Category.code = BelongsToCategory.category
         WHERE (BelongsToCategory.hat = Hat.code) AND (Category.public = true)) AS cat_count
FROM Hat
WHERE
    (SELECT COUNT(*)
     FROM BelongsToCategory
         JOIN Category ON Category.code = BelongsToCategory.category
         WHERE (BelongsToCategory.hat = Hat.code) AND (Category.public = true))
    >= 0
;

上述结果(使用> = 0): -

在此处输入图像描述

(使用 >=5):-

在此处输入图像描述

(使用 >=4):-

在此处输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM