我有一个包含一些数据的表格作为例子:
+----------+-----+------+
| order_id | poi | povi |
+----------+-----+------+
| 1 | A | a |
| 1 | B | b |
| 1 | C | c |
| 2 | A | a |
| 2 | B | b |
| 2 | C | c |
| 3 | A | a |
| 3 | B | b |
| 4 | C | c |
| 5 | A | a |
| 5 | B | b |
| 6 | C | c |
| 7 | A | a |
| 8 | B | b |
| 9 | C | c |
+----------+-----+------+
我有poi
和povi
的3组值,如{A,a},{B,b},{C,c}
我想得到包含所有这三个的order_id,就像在上面的情况下输出应该是。(order_id有poi和povi为{A,a}和{B,b}和{C,c}但是问题是它们是不同的行)
+----------+
| order_id |
+----------+
| 1 |
| 2 |
+----------+
任何想法?
答案 0 :(得分:2)
很多时候人们刚刚开始向已经提出并回答过的问题提出类似问题,包括这种常见情况。但是,无法对您的场景应用已知答案并不能帮助您了解所询问的内容,或查询在他们自己的场景中的工作方式......也就是说,让我们看看你的。
您希望所有DISTINCT订单包含以下所有A / a,B / b,C / c条目。有多种解决方法,但最常见的是使用where / group by / having。
从简单的事情开始,寻找任何有A / a
的订单select
yt.Order_id
from
YourTable yt
where
( yt.poi = 'A' AND yt.poiv = 'a' )
你会得到第1,2,3,5和7号订单。这很简单......
现在,添加您的其他条件
select
yt.Order_id
from
YourTable yt
where
( yt.poi = 'A' AND yt.poiv = 'a' )
OR ( yt.poi = 'B' AND yt.poiv = 'b' )
OR ( yt.poi = 'C' AND yt.poiv = 'c' )
这将为您提供所有行,但不是您想要的,但是您应该能够看到标准在哪里检查POI / POIV的两个部分,并在每个可能的组合之间使用OR。你显然不能有一个POI同时为“A”和“B”的记录,这就是每个配对(AND)标准之间“OR”的原因。但同样,这给了所有行。但它也只符合条件。所以让我们通过订单添加一个下一步...一个组,但HAVING子句期望3个记录......
select
ytA.Order_id
from
YourTable ytA
where
( yt.poi = 'A' AND yt.poiv = 'a' )
OR ( yt.poi = 'B' AND yt.poiv = 'b' )
OR ( yt.poi = 'C' AND yt.poiv = 'c' )
group by
yt.Order_id
HAVING
count(*) = 3
count(*)用于计算WHERE子句限定的记录数,并且只返回有3个条目的记录。
现在,如果有人有多个A / a,A / a,B / B订单怎么办?这可能会给出错误答案返回值,但请确认这些查询以满足您的需求。
虽然被接受,但这是我编写查询的另一种方式......有点类似于下面的另一篇文章。此版本查询的前提是在尝试查找ALL之前使用索引并限定至少找到1条记录。在这种情况下,它首先符合A / a的资格。如果订单没有,那就不在乎寻找B / b,C / c。如果它有,那么连接也有资格进入下一个级别
select
ytA.Order_id
from
YourTable ytA
JOIN YourTable ytB
on ytA.Order_id = ytB.Order_id
AND ytB.poi = 'B'
AND ytB.poiv = 'b'
JOIN YourTable ytC
on ytB.Order_id = ytC.Order_id
AND ytC.poi = 'C'
AND ytC.poiv = 'c'
where
ytA.poi = 'A'
AND ytA.poiv = 'a'
答案 1 :(得分:1)
找到列表的“交集”,每个列表包含一组
select id
from
(select id from mytable where poi = 'A' and povi= 'a') t1
inner join
(select id from mytable where poi = 'B' and povi= 'b') t2
using(id)
inner join
(select id from mytable where poi = 'C' and povi= 'c') t3
using(id)