【问题标题】:How to use a set algebra operation in SQL如何在 SQL 中使用集合代数运算
【发布时间】:2020-05-16 07:26:01
【问题描述】:

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

这是我目前所拥有的:

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

这不是使用集合代数运算。我对 SQL 真的很陌生,所以对此的任何帮助将不胜感激。

这是我从中获取数据的表:

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)); 

以及表'DRINKERS':

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

插入语句:

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

【问题讨论】:

  • 样本数据(INSERT 语句)和期望的结果会很有用
  • DRINK IN ('BEER', 'RED WINE'),但是我不确定这是否构成集合代数。
  • @Strawberry 更新了插入语句和所需的输出
  • 周围似乎有很多类似的问题;你们都在做同样的任务吗?
  • “集合代数”是什么意思?你的意思是 [tag:relational-algebra?] SQL 表包含行包,而不是行集。您是否被告知某些 SQL 运算符是它的“集合代数”运算符?为什么“必须使用集合代数运算来实现查询”以及“集合代数运算”在这里究竟是什么意思?请给出你的任务的确切措辞,不清楚你在问什么。

标签: mysql sql select algebra relational-algebra


【解决方案1】:

UNION是MySQL支持的集合代​​数运算,有两种形式:UNIONUNION ALL。前者只返回集合中不同的值,后者返回所有值(因此对于您的样本数据,将返回两次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

【讨论】:

    【解决方案2】:

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

    由于您没有指定某人是否喜欢某款饮品的评分,因此对于此查询,我们假设 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);
    

    假设“喜欢”的评分 >5,您将从您选择的 INSERT 语句中获得以下输出:

    CLAUDE
    JANUSZ
    JOHN
    TOM
    

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

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

    【讨论】:

    • 请注意 MySQL 不支持 INTERSECT 或 EXCEPT。
    • @EricMcCormick 。 . .您在此查询中拥有的 DISTINCTs 比必要的多。
    猜你喜欢
    • 2012-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-05
    • 1970-01-01
    • 1970-01-01
    • 2018-12-28
    • 1970-01-01
    相关资源
    最近更新 更多