【问题标题】:SQL: Syntax error with intersect?SQL:相交的语法错误?
【发布时间】:2010-02-20 16:46:51
【问题描述】:

这是我的查询:

-- Sids of suppliers who supply a green part AND a red part
(SELECT Suppliers.sid
FROM Suppliers
JOIN Catalog ON Catalog.sid = Suppliers.sid
JOIN Parts ON Parts.pid = Catalog.pid
WHERE Parts.color = "red")
INTERSECT
(SELECT Suppliers.sid
FROM Suppliers
JOIN Catalog ON Catalog.sid = Suppliers.sid
JOIN Parts ON Parts.pid = Catalog.pid
WHERE Parts.color = "green");

这是错误:

ERROR 1064 (42000):你有一个错误 在您的 SQL 语法中;检查手册 对应于您的 MySQL 服务器 使用正确语法的版本 靠近 “相交 (选择供应商.sid 来自供应商 JOIN Catalog ON Catalog.sid = Sup" 在第 6 行。

我做错了什么?

这是架构:

供应商(sid:整数,sname:字符串,地址字符串)

零件(pid:整数,pname:字符串,颜色:字符串)

目录(sid: integer, pid: integer, cost: real)

粗体 = 主键

【问题讨论】:

    标签: sql mysql intersect


    【解决方案1】:

    在 MySQL 中使用 INTERSECT 的另一种解决方案是使用 IN 子句。问题:“查找 2009 年秋季提供的课程的课程 ID 和 2010 年春季”

    //DML sample
    (select course_id
    from section
    where semester = ‘Fall’ and year = ‘2009’)
    intersect
    (select course_id
    from section
    where semester = ‘Spring’ and year = ‘2010’);
    

    在 MySQL 中:

    select distinct course_id
    from section
    where semester = 'Fall' and year= 2009 and
    course_id in (select course_id
    from section
    where semester = 'Spring' and year= 2010);
    

    如果您需要更多关于 IN 子句的信息,请在 Google 上搜索。

    【讨论】:

      【解决方案2】:

      您似乎正在使用的 MySQL 不支持 INTERSECT 语法。你将不得不以另一种方式解决它。

      在这种情况下,这很简单——我们只需要提供某个部分的“绿色”和“红色”的所有供应商的列表——您的查询不会费心查看这些部分本身是否相关,因此我们可以解决它很容易像这样:

      SELECT Suppliers.sid
      FROM Suppliers
      JOIN Catalog ON Catalog.sid = Suppliers.sid
      JOIN Parts ON Parts.pid = Catalog.pid
      WHERE Parts.color IN ('red', 'green')
      GROUP BY Suppliers.sid
      HAVING COUNT(DISTINCT Parts.color) = 2
      

      就个人而言,我不认为原始查询是典型的INTERSECT 问题。查看 Vinko Vrsalovic 提供的 JOIN 解决方案,以了解模拟 INTERSECT 的通用解决方案(顺便说一句,即使 RDBMS 实际上会原生提供 INTERSECT,我也会更喜欢它)。

      【讨论】:

      • 看看哪个更快,这个查询还是我的查询会很有趣——我认为它归结为哪个更快,第二个连接或按操作分组。
      • @Hogan,耸耸肩。这取决于很多东西:索引、哪个引擎、多少行、多少内存。 enless list...如果问题是找到最快的解决方案,我会采取完全不同的方法来回答这个问题。目前,我的模式是:如何重写标准 SQL 以获得等效结果,以防 MySQL 碰巧不支持该语法。
      • 点了,我想我总是处于最快的模式,而不是最清晰的模式。
      【解决方案3】:

      没什么,MySQL 没有 INTERSECT 关键字。您可以将其重写为 INNER JOIN:

      SELECT DISTINCT sid FROM
      (SELECT Suppliers.sid
      FROM Suppliers
      JOIN Catalog ON Catalog.sid = Suppliers.sid
      JOIN Parts ON Parts.pid = Catalog.pid
      WHERE Parts.color = "red") a
      INNER JOIN
      (SELECT Suppliers.sid
      FROM Suppliers
      JOIN Catalog ON Catalog.sid = Suppliers.sid
      JOIN Parts ON Parts.pid = Catalog.pid
      WHERE Parts.color = "green") b
      ON (a.sid = b.sid);
      

      这个查询当然可以写得更好,但这是为了表明 intersect 只是一个带有 select distinct 的内连接,您可以自动将一个转换为另一个。

      【讨论】:

      • 我基本同意,但INTERSECTINNER JOIN 并不完全相同。 INTERSECT 默认为 INTERSECT DISTINCT,这意味着它只需要返回唯一的行。在实际情况下,也可能在这种情况下,它会起作用,但要获得真正的重写,您必须添加 DISTINCTGROUP BY
      • 很酷。你现在得到了+1,因为我基本上认为JOININTERSECT 好得多:)我唯一一次看到相交,是在SQL 作业中;)
      • 例如,这里的另外两个答案是作为单个查询构建的,并且连接总数较少。
      【解决方案4】:

      这应该做你想做的:

      SELECT Suppliers.sid
      FROM Suppliers
      JOIN Catalog ON Catalog.sid = Suppliers.sid
      INNER JOIN Parts AS parts1 ON parts1.pid = Catalog.pid AND parts1.color = "red"
      INNER JOIN Parts AS parts2 ON parts2.pid = Catalog.pid AND parts2.color = "green"
      

      【讨论】:

      • 在这种情况下,我认为这不是问题所在。 MySQL 根本不支持INTERSECT
      • 而且该查询不会成功。 OP 希望所有 sid 都有绿色和红色部分。您的查询返回所有带有绿色或红色部分的 sid。
      • @Roland, @Vinko :是的,我看到了,我修复了答案,这应该做他想要的,并且比子查询更快。
      【解决方案5】:

      说明:

      假设我们有两个数据库表 T1 和 T2,我们需要两个表中的公共元素,那么我们可以使用 INTERSECT 操作,如上图所示。

      MySql 中没有 INTERSECT 运算符。所以我们可以用以下两个运算符来实现 INTERSECT 概念:

      1. IN 子句
      当我们想要一列作为 INTERSECT 操作的结果时,我们可以使用 IN 子句。

      2。存在子句
      当我们想要多列作为 INTERSECT 操作的结果时,我们可以使用 EXISTS 子句。

      有关更多详细信息,您可以阅读文档here

      答案:


      在上面提出的问题中,他们想要单列作为结果,因此我们可以使用 IN 子句,如下所示:

      SELECT Suppliers.sid FROM Suppliers 
      INNER JOIN Catalog ON Catalog.sid = Suppliers.sid 
      INNER JOIN Parts ON Parts.pid = Catalog.pid 
      WHERE Parts.color = "red"
      AND Suppliers.sid IN (
          SELECT Suppliers.sid
          FROM Suppliers
          INNER JOIN Catalog ON Catalog.sid = Suppliers.sid
          INNER JOIN Parts ON Parts.pid = Catalog.pid
          WHERE Parts.color = "green")
      

      【讨论】:

        【解决方案6】:

        我认为 SQL 不支持 INTERECT

        试试这个

        SELECT DISTINCT
        s.sid
        FROM
         suppliers s,
         catalog c
        WHERE
         s.sid = c.sid
         AND c.pid IN (SELECT 
         p1.pid
         FROM
         parts p1,
         parts p2
         WHERE
         p1.color = 'red' AND p2.color = 'green');
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-10-21
          • 1970-01-01
          • 2015-07-06
          • 1970-01-01
          • 1970-01-01
          • 2015-01-31
          • 2015-03-22
          相关资源
          最近更新 更多