1

我有一张最难的桌子

    One                        Two
   apple                      orange
   orange                     grapes 
   banana                     strawberry
   orange                     strawberry
   grapes                     apple

现在你可以看到我在这里列出了 5 对。让我告诉你,这不是一张普通的桌子,因为在这张桌子上,水果的名字(苹果)有时在第一列,有时在第二列。

And another table Description
name             color  
apple            red
orange           orange
strawberry       pink
banana           yellow
grapes           black

假设我是香蕉,我不想看到与我配对的水果的描述。 现在有人可以告诉我如何在mysql中显示与以下所有内容配对但不与香蕉配对的水果的详细信息:草莓、葡萄、苹果。

我说的是 mysql 不支持的方法。

Select * from description 
natural join (select one as name where two='apple' union select two as name where one='apple') as t1 
natural join (select one as name where two='grapes' union select two as name where one='grapes') as t2
natural join (select one as name where two='strawberry' union select two as name where one='strawberry') as t3
MINUS
Select * from description 
natural join (select one as name where two='banana' union select two as name where one='banana') as b6
4

4 回答 4

3
SELECT * FROM Description
NATURAL JOIN (
  SELECT One AS name FROM hardest WHERE Two = 'strawberry'
  UNION
  SELECT Two AS name FROM hardest WHERE One = 'strawberry'
) AS t1
NATURAL JOIN (
  SELECT One AS name FROM hardest WHERE Two = 'grapes'
  UNION
  SELECT Two AS name FROM hardest WHERE One = 'grapes'
) AS t2
NATURAL JOIN (
  SELECT One AS name FROM hardest WHERE Two = 'apple'
  UNION
  SELECT Two AS name FROM hardest WHERE One = 'apple'
) AS t3;

更新

bananaOP 更新了问题,添加了结果集应排除与;配对的任何水果的约束。然后他提出了一个使用 的解决方案WHERE name NOT IN ( SELECT ... ),但质疑外连接是否更有效。

首先,使用外连接的查询:

SELECT Description.* FROM Description
NATURAL JOIN (
  SELECT One AS name FROM hardest WHERE Two = 'strawberry'
  UNION
  SELECT Two AS name FROM hardest WHERE One = 'strawberry'
) AS t1
NATURAL JOIN (
  SELECT One AS name FROM hardest WHERE Two = 'grapes'
  UNION
  SELECT Two AS name FROM hardest WHERE One = 'grapes'
) AS t2
NATURAL JOIN (
  SELECT One AS name FROM hardest WHERE Two = 'apple'
  UNION
  SELECT Two AS name FROM hardest WHERE One = 'apple'
) AS t3
NATURAL LEFT JOIN (
  SELECT One AS name, TRUE As hasBanana FROM hardest WHERE Two = 'banana'
  UNION
  SELECT Two AS name, TRUE As hasBanana FROM hardest WHERE One = 'banana'
) AS t4
WHERE hasBanana IS NULL;

关于哪个更有效,本文比较了不同的方法。它指出(关于[NOT] IN ( SELECT ... )

LEFT JOIN本质上,这与/使用的计划完全相同IS NULL,尽管这些计划是由不同的代码分支执行的,并且它们在EXPLAIN. 算法实际上是相同的,并且查询在同一时间完成。

于 2012-04-27T11:27:05.800 回答
0

请确保我的写作方式是最有效的。如果您有其他更有效的方式,请写

 SELECT * FROM Description 
   NATURAL JOIN (   SELECT One AS name FROM hardest WHERE Two = 'strawberry'  
     UNION SELECT Two AS name FROM hardest WHERE One = 'strawberry' ) AS t1
   NATURAL JOIN (   SELECT One AS name FROM hardest WHERE Two = 'grapes'  
     UNION   SELECT Two AS name FROM hardest WHERE One = 'grapes' ) AS t2 
   NATURAL JOIN (   SELECT One AS name FROM hardest WHERE Two = 'apples' 
     UNION   SELECT Two AS name FROM hardest WHERE One = 'apples' ) AS t3
    where name not in ( SELECT One AS name FROM hardest WHERE Two = 'banana' 
     UNION   SELECT Two AS name FROM hardest WHERE One = 'banana') AS fz );
于 2012-04-28T12:08:31.293 回答
0

我正在清理我的答案,因为问题正在远离原始问题。

于 2012-04-27T11:20:26.683 回答
0

嗨,您有自己查询的答案,您必须使用IN. =请检查下面的查询...

select * from hardest,description where 
   (one=name and two IN ('apple' , 'strawberry','grapes')) 
   or 
   (one IN ('apple','strawberry' , 'grapes') and two=name)

谢谢

于 2012-04-27T12:34:14.550 回答