您如何使连接子句显示来自相同 table 的 (ingredient1,ingredient2)
How can you make a join clause displaying (ingredient1,ingredient2) from the same table
我有 4 个 table,其中 2 个是这个问题所必需的:
CREATE TABLE Ingredient_sets
(
recipe_id NUMBER(3,0),
ingred_id NUMBER(3,0),
quantity NUMBER(5,2),
um VARCHAR2(10) NOT NULL),
comments VARCHAR2(100)
);
CREATE TABLE Ingredient
(
ingred_id NUMBER(3,0),
ingredient VARCHAR2(30)
);
我必须做一个加入声明。它应该显示成分 1、成分 2,其中成分在同一配方中(因此 recipe_id
相同),具有相同的计量单位(um
)和相同的数量。
结果对应该只出现一次!
ingred_id
是 Ingredient
中的主键 table 和 Ingredient_sets
中的外键 table:
ALTER TABLE Ingredient
MODIFY (CONSTRAINT ingred_id_pk PRIMARY KEY (ingred_id));
ALTER TABLE Ingredient_sets
MODIFY (CONSTRAINT ingred_id_fk FOREIGN KEY (ingred_id)
REFERENCES Ingredient(ingred_id) ON DELETE CASCADE);
Recipe_id
是其 table 的主键。
直到现在我尝试了不同的连接语句,但没有任何效果
如果 table Ingredient_sets
有主键,解决方案会更简单。没有它,您可以使用 DISTINCT
删除重复项的查询。查询可能如下所示:
select distinct a.recipe_id, a.ingred_id, a.um, a.quantity
from Ingredient_sets a
join Ingredient_sets b
on a.recipe_id = b.recipe_id
and a.ingred_id = b.ingred_id
and a.um = b.um
and a.quantity = b.quantity
在 recipe_id & um & 数量上使用自连接。
还有更高(或更低)的 ingred_id.
然后你只得到一次二重奏。
示例数据
CREATE TABLE Ingredient
(
ingred_id NUMBER(3,0),
ingredient VARCHAR2(30),
CONSTRAINT ingred_id_pk PRIMARY KEY (ingred_id)
);
CREATE TABLE Ingredient_sets
(
recipe_id NUMBER(3,0),
ingred_id NUMBER(3,0),
quantity NUMBER(5,2),
um VARCHAR2(10) NOT NULL,
comments VARCHAR2(100),
CONSTRAINT ingred_id_fk FOREIGN KEY (ingred_id)
REFERENCES Ingredient(ingred_id) ON DELETE CASCADE
);
INSERT ALL
INTO Ingredient VALUES (1, 'Butter')
INTO Ingredient VALUES (2, 'Milk')
INTO Ingredient VALUES (3, 'Egg')
SELECT 1 FROM DUAL;
INSERT INTO Ingredient_sets
(recipe_id, ingred_id, quantity, um, comments)
SELECT 1, 1, 20.2, 'gram', 'greasy stuff' FROM DUAL UNION ALL
SELECT 1, 2, 20.2, 'gram', 'liquid stuff' FROM DUAL UNION ALL
SELECT 1, 3, 2.0, 'piece', 'slimey stuff' FROM DUAL
查询:
select
set1.recipe_id
, set1.um
, set1.quantity
, set1.ingred_id as ingred_id1
, ing1.ingredient as ingredient1
, set2.ingred_id as ingred_id2
, ing2.ingredient as ingredient2
from Ingredient_sets set1
join Ingredient_sets set2
on set2.recipe_id = set1.recipe_id
and set2.um = set1.um
and set2.quantity = set1.quantity
and set2.ingred_id > set1.ingred_id
left join Ingredient ing1 on ing1.ingred_id = set1.ingred_id
left join Ingredient ing2 on ing2.ingred_id = set2.ingred_id
RECIPE_ID | UM | QUANTITY | INGRED_ID1 | INGREDIENT1 | INGRED_ID2 | INGREDIENT2
--------: | :--- | -------: | ---------: | :---------- | ---------: | :----------
1 | gram | 20.2 | 1 | Butter | 2 | Milk
或者使用 COUNT OVER
过滤那些没有唯一的 um 和每组数量的。
select *
from
(
select
ingset.*
, ing.ingredient
, count(*) over (partition by recipe_id, um, quantity) as same
from Ingredient_sets ingset
left join Ingredient ing on ing.ingred_id = ingset.ingred_id
) q
where same > 1
order by recipe_id, um, quantity
RECIPE_ID | INGRED_ID | QUANTITY | UM | COMMENTS | INGREDIENT | SAME
--------: | --------: | -------: | :--- | :----------- | :--------- | ---:
1 | 1 | 20.2 | gram | greasy stuff | Butter | 2
1 | 2 | 20.2 | gram | liquid stuff | Milk | 2
db<>fiddle here
我有 4 个 table,其中 2 个是这个问题所必需的:
CREATE TABLE Ingredient_sets
(
recipe_id NUMBER(3,0),
ingred_id NUMBER(3,0),
quantity NUMBER(5,2),
um VARCHAR2(10) NOT NULL),
comments VARCHAR2(100)
);
CREATE TABLE Ingredient
(
ingred_id NUMBER(3,0),
ingredient VARCHAR2(30)
);
我必须做一个加入声明。它应该显示成分 1、成分 2,其中成分在同一配方中(因此 recipe_id
相同),具有相同的计量单位(um
)和相同的数量。
结果对应该只出现一次!
ingred_id
是 Ingredient
中的主键 table 和 Ingredient_sets
中的外键 table:
ALTER TABLE Ingredient
MODIFY (CONSTRAINT ingred_id_pk PRIMARY KEY (ingred_id));
ALTER TABLE Ingredient_sets
MODIFY (CONSTRAINT ingred_id_fk FOREIGN KEY (ingred_id)
REFERENCES Ingredient(ingred_id) ON DELETE CASCADE);
Recipe_id
是其 table 的主键。
直到现在我尝试了不同的连接语句,但没有任何效果
如果 table Ingredient_sets
有主键,解决方案会更简单。没有它,您可以使用 DISTINCT
删除重复项的查询。查询可能如下所示:
select distinct a.recipe_id, a.ingred_id, a.um, a.quantity
from Ingredient_sets a
join Ingredient_sets b
on a.recipe_id = b.recipe_id
and a.ingred_id = b.ingred_id
and a.um = b.um
and a.quantity = b.quantity
在 recipe_id & um & 数量上使用自连接。
还有更高(或更低)的 ingred_id.
然后你只得到一次二重奏。
示例数据
CREATE TABLE Ingredient ( ingred_id NUMBER(3,0), ingredient VARCHAR2(30), CONSTRAINT ingred_id_pk PRIMARY KEY (ingred_id) ); CREATE TABLE Ingredient_sets ( recipe_id NUMBER(3,0), ingred_id NUMBER(3,0), quantity NUMBER(5,2), um VARCHAR2(10) NOT NULL, comments VARCHAR2(100), CONSTRAINT ingred_id_fk FOREIGN KEY (ingred_id) REFERENCES Ingredient(ingred_id) ON DELETE CASCADE ); INSERT ALL INTO Ingredient VALUES (1, 'Butter') INTO Ingredient VALUES (2, 'Milk') INTO Ingredient VALUES (3, 'Egg') SELECT 1 FROM DUAL; INSERT INTO Ingredient_sets (recipe_id, ingred_id, quantity, um, comments) SELECT 1, 1, 20.2, 'gram', 'greasy stuff' FROM DUAL UNION ALL SELECT 1, 2, 20.2, 'gram', 'liquid stuff' FROM DUAL UNION ALL SELECT 1, 3, 2.0, 'piece', 'slimey stuff' FROM DUAL
查询:
select set1.recipe_id , set1.um , set1.quantity , set1.ingred_id as ingred_id1 , ing1.ingredient as ingredient1 , set2.ingred_id as ingred_id2 , ing2.ingredient as ingredient2 from Ingredient_sets set1 join Ingredient_sets set2 on set2.recipe_id = set1.recipe_id and set2.um = set1.um and set2.quantity = set1.quantity and set2.ingred_id > set1.ingred_id left join Ingredient ing1 on ing1.ingred_id = set1.ingred_id left join Ingredient ing2 on ing2.ingred_id = set2.ingred_id
RECIPE_ID | UM | QUANTITY | INGRED_ID1 | INGREDIENT1 | INGRED_ID2 | INGREDIENT2 --------: | :--- | -------: | ---------: | :---------- | ---------: | :---------- 1 | gram | 20.2 | 1 | Butter | 2 | Milk
或者使用 COUNT OVER
过滤那些没有唯一的 um 和每组数量的。
select * from ( select ingset.* , ing.ingredient , count(*) over (partition by recipe_id, um, quantity) as same from Ingredient_sets ingset left join Ingredient ing on ing.ingred_id = ingset.ingred_id ) q where same > 1 order by recipe_id, um, quantity
RECIPE_ID | INGRED_ID | QUANTITY | UM | COMMENTS | INGREDIENT | SAME --------: | --------: | -------: | :--- | :----------- | :--------- | ---: 1 | 1 | 20.2 | gram | greasy stuff | Butter | 2 1 | 2 | 20.2 | gram | liquid stuff | Milk | 2
db<>fiddle here