查找具有多个链接行的行
find rows that have multiple linked rows
我正在做我的高中项目
我想 运行 查询用户使用多个类别搜索药物
这是 ddl,
Create table medicine (
MedId int(11) NOT NULL AUTO_INCREMENT,
Name varchar(30) COLLATE utf8_bin DEFAULT NULL,
Vendor varchar(20) COLLATE utf8_bin DEFAULT NULL,
Quantity int(11) NOT NULL,
type text COLLATE utf8_bin NOT NULL,
price int(11) NOT NULL,
PRIMARY KEY (MedId)
);
create table category(
CatId smallint auto_increment,
Name varchar (20),
primary key(CatID)
);
create table MedicineCat(
MedId int,
CatId smallint,
foreign key (MedId) references medicine(MedId),
foreign key (CatId) references category(CatId),
primary key(MedId,CatId)
);
SELECT medicinecat.MedID AS 'MedId', medicine.Name AS 'Name', medicine.price AS 'Price', medicine.Quantity AS 'Quantity'
FROM medicinecat
JOIN medicine ON medicine.MedId = medicinecat.MedId
WHERE CatId in (1,2,3);
我得到的是至少有一个类别的所有药物,我知道那是因为 IN 条款,
我想要的是 select "all the categories" 不属于该类别的药物。
select
m.MedID AS 'MedId',
m.Name AS 'Name',
m.price AS 'Price',
m.Quantity AS 'Quantity'
from medicine as m
where
exists (
-- to get only those having all three categories
select 1
from medicinecat as mc
where mc.CatId in (1,2,3) and mc.MedID = m.MedID
having count(*) = 3
)
如果你能做一些通用的解决方案,比如
select
m.MedID AS 'MedId',
m.Name AS 'Name',
m.price AS 'Price',
m.Quantity AS 'Quantity'
from medicine as m
where
not exists (
select *
from (values (1), (2), (3)) as tt(CatId)
left outer join medicinecat as mc on mc.CatId = tt.CatId and mc.MedID = m.MedID
where mc.CatId is null
)
或
select
m.MedID AS 'MedId',
m.Name AS 'Name',
m.price AS 'Price',
m.Quantity AS 'Quantity'
from medicine as m
where
exists (
-- to get only those having all categories
select 1
from (values (1), (2), (3)) as tt(CatId)
left outer join medicinecat as mc on mc.CatId = tt.CatId and mc.MedID = m.MedID
having count(tt.CatId) = count(mc.CatId)
)
几个选项(未经测试)
类别数
声明@categoryCount int
SET @categoryCount = (SELECT COUNT(*) FROM 类别 WHERE catid IN (1,2,3))
SELECT medicine.MedID AS 'MedId', medicine.Name AS 'Name', medicine.price AS 'Price', medicine.Quantity AS 'Quantity'
FROM Medicine
WHERE @categoryCount = (SELECT COUNT(*) FROM MedicineCat WHERE MedicineCat.MedId = Medicine.MedId)
分组依据 + 具有
SELECT medicine.MedID AS 'MedId', medicine.Name AS 'Name', medicine.price AS 'Price', medicine.Quantity AS 'Quantity'
FROM Medicine
JOIN MedicineCat ON Medicine.MedId = MedicineCat.MedId
GROUP BY medicine.MedID, medicine.Name, medicine.price, medicine.Quantity
HAVING COUNT(*) = @categoryCount
多个存在
SELECT medicine.MedID AS 'MedId', medicine.Name AS 'Name', medicine.price AS 'Price', medicine.Quantity AS 'Quantity'
FROM Medicine
WHERE EXISTS (SELECT 1 FROM MedicineCat WHERE MedicineCat.MedId = 1)
AND EXISTS (SELECT 1 FROM MedicineCat WHERE MedicineCat.MedId = 2)
AND EXISTS (SELECT 1 FROM MedicineCat WHERE MedicineCat.MedId = 3)
我正在做我的高中项目 我想 运行 查询用户使用多个类别搜索药物 这是 ddl,
Create table medicine (
MedId int(11) NOT NULL AUTO_INCREMENT,
Name varchar(30) COLLATE utf8_bin DEFAULT NULL,
Vendor varchar(20) COLLATE utf8_bin DEFAULT NULL,
Quantity int(11) NOT NULL,
type text COLLATE utf8_bin NOT NULL,
price int(11) NOT NULL,
PRIMARY KEY (MedId)
);
create table category(
CatId smallint auto_increment,
Name varchar (20),
primary key(CatID)
);
create table MedicineCat(
MedId int,
CatId smallint,
foreign key (MedId) references medicine(MedId),
foreign key (CatId) references category(CatId),
primary key(MedId,CatId)
);
SELECT medicinecat.MedID AS 'MedId', medicine.Name AS 'Name', medicine.price AS 'Price', medicine.Quantity AS 'Quantity'
FROM medicinecat
JOIN medicine ON medicine.MedId = medicinecat.MedId
WHERE CatId in (1,2,3);
我得到的是至少有一个类别的所有药物,我知道那是因为 IN 条款, 我想要的是 select "all the categories" 不属于该类别的药物。
select
m.MedID AS 'MedId',
m.Name AS 'Name',
m.price AS 'Price',
m.Quantity AS 'Quantity'
from medicine as m
where
exists (
-- to get only those having all three categories
select 1
from medicinecat as mc
where mc.CatId in (1,2,3) and mc.MedID = m.MedID
having count(*) = 3
)
如果你能做一些通用的解决方案,比如
select
m.MedID AS 'MedId',
m.Name AS 'Name',
m.price AS 'Price',
m.Quantity AS 'Quantity'
from medicine as m
where
not exists (
select *
from (values (1), (2), (3)) as tt(CatId)
left outer join medicinecat as mc on mc.CatId = tt.CatId and mc.MedID = m.MedID
where mc.CatId is null
)
或
select
m.MedID AS 'MedId',
m.Name AS 'Name',
m.price AS 'Price',
m.Quantity AS 'Quantity'
from medicine as m
where
exists (
-- to get only those having all categories
select 1
from (values (1), (2), (3)) as tt(CatId)
left outer join medicinecat as mc on mc.CatId = tt.CatId and mc.MedID = m.MedID
having count(tt.CatId) = count(mc.CatId)
)
几个选项(未经测试)
类别数 声明@categoryCount int SET @categoryCount = (SELECT COUNT(*) FROM 类别 WHERE catid IN (1,2,3))
SELECT medicine.MedID AS 'MedId', medicine.Name AS 'Name', medicine.price AS 'Price', medicine.Quantity AS 'Quantity'
FROM Medicine
WHERE @categoryCount = (SELECT COUNT(*) FROM MedicineCat WHERE MedicineCat.MedId = Medicine.MedId)
分组依据 + 具有
SELECT medicine.MedID AS 'MedId', medicine.Name AS 'Name', medicine.price AS 'Price', medicine.Quantity AS 'Quantity'
FROM Medicine
JOIN MedicineCat ON Medicine.MedId = MedicineCat.MedId
GROUP BY medicine.MedID, medicine.Name, medicine.price, medicine.Quantity
HAVING COUNT(*) = @categoryCount
多个存在
SELECT medicine.MedID AS 'MedId', medicine.Name AS 'Name', medicine.price AS 'Price', medicine.Quantity AS 'Quantity'
FROM Medicine
WHERE EXISTS (SELECT 1 FROM MedicineCat WHERE MedicineCat.MedId = 1)
AND EXISTS (SELECT 1 FROM MedicineCat WHERE MedicineCat.MedId = 2)
AND EXISTS (SELECT 1 FROM MedicineCat WHERE MedicineCat.MedId = 3)