我正在尝试简化where子句,因此我不必列出表格中的每一列。
一个例子是这样的:
SELECT Drink_Name
FROM Answer
WHERE Gin IS NOT NULL
AND Rum IS NOT NULL
AND Vodka IS NOT NULL
AND Lager IS NULL
AND Cider IS NULL
AND Tequila IS NULL
AND Whiskey IS NULL
AND Baileys IS NULL
AND Cola IS NULL
Drink_Name Baileys Cider Cola Gin Lager Rum Tequila Vodka Whiskey
Mary Hinge NULL NULL NULL NULL NULL 1 NULL NULL 1
Ringsting NULL 1 1 NULL NULL NULL 1 NULL 1
Stonehenge NULL 1 NULL 1 1 1 NULL 1 NULL
Typhoon Lagoon NULL NULL NULL 1 NULL 1 NULL 1 NULL
Wet and Wild 1 NULL 1 NULL NULL NULL 1 1 NULL
Drink_NameID
Drink_Name
Drink_NameID
Ingredient_Name
Mary Hinge
Ringsting
Stonehenge
Typhoon Lagoon
Wet and Wild
Baileys
Cider
Cola
Gin
Lager
Rum
Tequila
Vodka
Whiskey
答案 0 :(得分:0)
(这不是一个答案,但对评论来说太大了)
您要求简化您的where子句,以便选择仅包含Gin,Rum,Vodka的Drink_Names
在您当前的版本中,您的查询将如下所示:
SELECT Drink_Name
FROM Answer
WHERE Gin IS NOT NULL AND Rum IS NOT NULL AND Vodka IS NOT NULL;
你被告知要让你的结构变得更好。好的,你的结构看起来像这样(我省略了外键,ids等):
create view good_structure as
select drink_name, drink_type, amount from answer
unpivot exclude nulls(
amount for drink_type in (baileys as 'baileys', cider as 'cider', cola as 'cola', gin as 'gin', lager as 'lager',
rum as 'rum', tequila as 'tequila', vodka as 'vodka', whiskey as 'whiskey')
);
通过这种良好的结构,我们可以简化您的查询:
SELECT distinct Drink_Name
FROM good_structure g
WHERE exists (select 1 from good_structure g2 where g2.drink_name = g.drink_name and g2.drink_type = 'Gin' and g2.amount > 0)
AND exists (select 1 from good_structure g2 where g2.drink_name = g.drink_name and g2.drink_type = 'Rum' and g2.amount > 0)
AND exists (select 1 from good_structure g2 where g2.drink_name = g.drink_name and g2.drink_type = 'Vodka' and g2.amount > 0);
更简单:)
因此,如果您的目的是简化查询,那么当前的简单就足够了。如果你想要一个好的设计而不是我想它是另一个问题......
这是一些重构脚本,可以帮助您理解:
-- remove all
drop table drink_recipes;
drop table ingredients;
drop table drinks;
drop sequence drinks_seq;
drop sequence ingredients_seq;
drop sequence drink_recipes_seq;
-- create tables
create table DRINKS (drink_id number(10) primary key, drink_name varchar2(255));
create table INGREDIENTS (ingredient_id number(10) primary key, ingredient_name varchar2(255));
create table DRINK_RECIPES (
recipe_id number(10) primary key,
drink_id number(10) references DRINKS(drink_id),
ingredient_id number(10) references INGREDIENTS(ingredient_id),
amount number(5)
);
-- recipe_id may be redundant
-- create sequences (if needed)
create sequence drinks_seq;
create sequence ingredients_seq;
create sequence drink_recipes_seq;
-- fill the data
insert into drinks
select drinks_seq.nextval, drink_name from (select distinct drink_name from answer);
insert into INGREDIENTS
with unpivoted as (
select drink_name, drink_type, amount from answer
unpivot exclude nulls(
amount for drink_type in (baileys as 'baileys', cider as 'cider', cola as 'cola', gin as 'gin', lager as 'lager',
rum as 'rum', tequila as 'tequila', vodka as 'vodka', whiskey as 'whiskey')
)
)
select ingredients_seq.nextval, drink_type from (
select distinct drink_type from unpivoted);
insert into DRINK_RECIPES
with unpivoted as (
select drink_name, drink_type, amount from answer
unpivot exclude nulls(
amount for drink_type in (baileys as 'baileys', cider as 'cider', cola as 'cola', gin as 'gin', lager as 'lager',
rum as 'rum', tequila as 'tequila', vodka as 'vodka', whiskey as 'whiskey')
)
),
help as (
select d.drink_id, i.ingredient_id, u.amount
from unpivoted u join drinks d on u.drink_name = d.drink_name
join ingredients i on u.drink_type = i.ingredient_name
)
select drink_recipes_seq.nextval, drink_id, ingredient_id, amount from help;