SQL 子集查询
SQL subsets query
我在为 SQL table 创建查询时遇到问题。我尝试创建的查询显示 "clothes" 类别中的产品数量,但不显示配饰,例如作为 T 恤或运动衫输入的产品列表。
这是已创建的 table:
CREATE DATABASE IF NOT EXISTS product_list;
DROP TABLE IF EXISTS products;
DROP TABLE IF EXISTS product_categories;
DROP TABLE IF EXISTS categories;
CREATE TABLE products (
product_id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(50) DEFAULT NULL,
active BOOL DEFAULT NULL
);
CREATE TABLE categories (
category_id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50),
structure VARCHAR(50)
);
CREATE TABLE product_categories (
product_id INT,
category_id INT,
PRIMARY KEY(product_id, category_id)
);
INSERT INTO products VALUES
(NULL, "Blue Sweatshirt", false),
(NULL, "Short Sleeve T-Shirt", true),
(NULL, "White Vest", true),
(NULL, "Black Hairclip", true),
(NULL, "Knitted Hat", false),
(NULL, "Grey Sweatshirt", true),
(NULL, "Tartan Scarf", true);
INSERT INTO categories VALUES
(NULL, "Sweatshirts", "Clothes>Sweatshirts"),
(NULL, "T-Shirts", "Clothes>T-Shirts"),
(NULL, "Accessories", "Accessories"),
(NULL, "Winter", "Clothes>Winter"),
(NULL, "Vests", "Clothes>Vests");
INSERT INTO product_categories VALUES
(1, 1), (2, 2), (3, 5), (3, 4), (4, 3), (5, 3), (5, 4), (6, 1), (7, 3), (7, 4);
试试这个查询
select * from products a
join Product_categories b on a.product_id=b.product_id
join categories c on b.category_id=b.category_id
where c.name like '%Clothes%'
如果我没理解错的话,这是一个集合中的查询。您正在寻找至少具有一个 "clothes" 类别的产品,其中 none 个类别不是衣服。我使用 group by
和 having
来解决这个问题,因为它非常灵活:
select pc.product_id
from Product_categories pc join
categories c
on pc.category_id = c.category_id
group by pc.product_id
having sum(case when c.structure like 'Clothes%' then 1 else 0 end) > 0 and
sum(case when c.structure not like 'Clothes%' then 1 else 0 end) = 0;
如果你只想要计数,那么你可以将其用作子查询并使用 count(*)
.
编辑:
一个小纸条。这个问题现在用 MySQL 标记,它是 having
子句的方便简写:
having sum(c.structure like 'Clothes%') > 0 and
sum(c.structure not like 'Clothes%') = 0;
我在为 SQL table 创建查询时遇到问题。我尝试创建的查询显示 "clothes" 类别中的产品数量,但不显示配饰,例如作为 T 恤或运动衫输入的产品列表。
这是已创建的 table:
CREATE DATABASE IF NOT EXISTS product_list;
DROP TABLE IF EXISTS products;
DROP TABLE IF EXISTS product_categories;
DROP TABLE IF EXISTS categories;
CREATE TABLE products (
product_id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(50) DEFAULT NULL,
active BOOL DEFAULT NULL
);
CREATE TABLE categories (
category_id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50),
structure VARCHAR(50)
);
CREATE TABLE product_categories (
product_id INT,
category_id INT,
PRIMARY KEY(product_id, category_id)
);
INSERT INTO products VALUES
(NULL, "Blue Sweatshirt", false),
(NULL, "Short Sleeve T-Shirt", true),
(NULL, "White Vest", true),
(NULL, "Black Hairclip", true),
(NULL, "Knitted Hat", false),
(NULL, "Grey Sweatshirt", true),
(NULL, "Tartan Scarf", true);
INSERT INTO categories VALUES
(NULL, "Sweatshirts", "Clothes>Sweatshirts"),
(NULL, "T-Shirts", "Clothes>T-Shirts"),
(NULL, "Accessories", "Accessories"),
(NULL, "Winter", "Clothes>Winter"),
(NULL, "Vests", "Clothes>Vests");
INSERT INTO product_categories VALUES
(1, 1), (2, 2), (3, 5), (3, 4), (4, 3), (5, 3), (5, 4), (6, 1), (7, 3), (7, 4);
试试这个查询
select * from products a
join Product_categories b on a.product_id=b.product_id
join categories c on b.category_id=b.category_id
where c.name like '%Clothes%'
如果我没理解错的话,这是一个集合中的查询。您正在寻找至少具有一个 "clothes" 类别的产品,其中 none 个类别不是衣服。我使用 group by
和 having
来解决这个问题,因为它非常灵活:
select pc.product_id
from Product_categories pc join
categories c
on pc.category_id = c.category_id
group by pc.product_id
having sum(case when c.structure like 'Clothes%' then 1 else 0 end) > 0 and
sum(case when c.structure not like 'Clothes%' then 1 else 0 end) = 0;
如果你只想要计数,那么你可以将其用作子查询并使用 count(*)
.
编辑:
一个小纸条。这个问题现在用 MySQL 标记,它是 having
子句的方便简写:
having sum(c.structure like 'Clothes%') > 0 and
sum(c.structure not like 'Clothes%') = 0;