如何在 SQL 中使用集合代数运算

How to use a set algebra operation in SQL

我需要找到喜欢啤酒或红酒的不同饮酒者。但是,查询必须使用集合代数运算来实现。

这是我目前的情况:

SELECT DRINKER 
FROM LIKES 
WHERE DRINK = 'BEER' OR 'RED WINE'; 

虽然这不是使用集合代数运算。我是 SQL 的新手,因此非常感谢您对此提供任何帮助。

这是 table 我从以下位置获取数据:

CREATE TABLE LIKES( /* Drinkers like drinks */
DRINKER     VARCHAR(30) NOT NULL,   /* Drinker name */
DRINK       VARCHAR(30) NOT NULL,   /* Drink name   */
RATING      DECIMAL(1)  NOT NULL,   /* Rating of the drink  */
    CONSTRAINT LIKES_PKEY PRIMARY KEY(DRINKER, DRINK),
    CONSTRAINT LIKES_FKEY1 FOREIGN KEY(DRINK) REFERENCES ALLDRINKS(DRINK),
    CONSTRAINT LIKES_DKEY2 FOREIGN KEY(DRINKER) REFERENCES DRINKERS(DRINKER)); 

以及 table 'DRINKERS':

CREATE TABLE DRINKERS ( /* All drinkers */
DRINKER VARCHAR(30) NOT NULL,
    CONSTRAINT DRINKERS_PKEY PRIMARY KEY (DRINKER));

INSERT 语句:

INSERT INTO LIKES VALUES('TOM', 'BEER', 6);
INSERT INTO LIKES VALUES('JANUSZ', 'VODKA', 6);
INSERT INTO LIKES VALUES('JANUSZ', 'RUM', 5);
INSERT INTO LIKES VALUES('JANUSZ', 'BEER', 6);
INSERT INTO LIKES VALUES('JANUSZ', 'CHAMPAGNE', 6);
INSERT INTO LIKES VALUES('JANUSZ', 'RED WINE', 6);
INSERT INTO LIKES VALUES('JANUSZ', 'WHITE WINE', 5);
INSERT INTO LIKES VALUES('JANUSZ', 'PORT', 5);
INSERT INTO LIKES VALUES('PETER', 'CHAMPAGNE', 4);
INSERT INTO LIKES VALUES('PETER', 'COGNAC', 3);
INSERT INTO LIKES VALUES('PETER', 'RUM', 3);
INSERT INTO LIKES VALUES('PETER', 'WHISKY', 6);
INSERT INTO LIKES VALUES('MARY', 'CHAMPAGNE', 5);
INSERT INTO LIKES VALUES('MARY', 'VODKA', 1);
INSERT INTO LIKES VALUES('MARY', 'COGNAC', 4);
INSERT INTO LIKES VALUES('JOHN', 'CHAMPAGNE', 4);
INSERT INTO LIKES VALUES('JOHN', 'VODKA', 2);
INSERT INTO LIKES VALUES('JOHN', 'RUM', 6);
INSERT INTO LIKES VALUES('JOHN', 'WHISKY', 1);
INSERT INTO LIKES VALUES('JOHN', 'BEER', 6);
INSERT INTO LIKES VALUES('JAMES', 'CHAMPAGNE', 6);
INSERT INTO LIKES VALUES('JAMES', 'COGNAC', 5);
INSERT INTO LIKES VALUES('JAMES', 'RUM', 4);
INSERT INTO LIKES VALUES('SERGIEY', 'VODKA', 6);
INSERT INTO LIKES VALUES('SERGIEY', 'RUM', 6);
INSERT INTO LIKES VALUES('SERGIEY', 'CHAMPAGNE', 3);
INSERT INTO LIKES VALUES('CLAUDE', 'CHAMPAGNE', 6);
INSERT INTO LIKES VALUES('CLAUDE', 'WHITE WINE', 5);
INSERT INTO LIKES VALUES('CLAUDE', 'COGNAC', 4);
INSERT INTO LIKES VALUES('CLAUDE', 'WHISKY', 3);
INSERT INTO LIKES VALUES('CLAUDE', 'RED WINE', 6);

期望的输出:

DRINKER

JANUSZ
JOHN
TOM

在标准SQL中,集合代数运算是 UNION、INTERSECT 和 EXCEPT。对于您的需求,我认为UNION会是最好的选择。

由于您没有具体说明某人是否喜欢饮料的评分,对于此查询,我们假设 <=5 表示他们不喜欢它,>5 表示他们喜欢它。

SELECT DISTINCT DRINKER
FROM (SELECT DISTINCT DRINKER
      FROM LIKES
      WHERE DRINK="BEER"
      AND RATING>5
      UNION
      SELECT DISTINCT DRINKER
      FROM LIKES
      WHERE DRINK="RED WINE"
      AND RATING>5);

使用 "Likes" 的假设是评级 >5,您将从您选择的 INSERT 语句中获得此输出:

CLAUDE
JANUSZ
JOHN
TOM

您可以在此处阅读有关集合操作的更多信息:

https://en.wikipedia.org/wiki/Set_operations_(SQL)

UNION是MySQL支持的集合代​​数运算,有两种形式:UNIONUNION ALL。前者 returns 仅与集合不同的值,后者所有值(因此对于您的样本数据, return JANUSZ 两次,因为他们喜欢 BEERRED WINE).因此,用于查找喜欢 BEERRED WINE 的饮酒者的集合代数查询将是:

SELECT DRINKER
FROM LIKES
WHERE DRINK = 'BEER'
UNION
SELECT DRINKER 
FROM LIKES 
WHERE DRINK = 'RED WINE'

示例数据的输出:

DRINKER
TOM
JANUSZ
JOHN
CLAUDE

(注意CLAUDE也喜欢RED WINE)

Demo on dbfiddle

您可以将 ORDER BY 子句添加到 UNION 以对最终结果进行排序。没有一个,结果的顺序就无法保证。例如按字母顺序排序:

SELECT DRINKER
FROM LIKES
WHERE DRINK = 'BEER'
UNION
SELECT DRINKER 
FROM LIKES 
WHERE DRINK = 'RED WINE'
ORDER BY DRINKER

输出:

DRINKER
CLAUDE
JANUSZ
JOHN
TOM

Demo on dbfiddle