MySQL-根据条件选择行

时间:2020-04-24 18:09:03

标签: mysql sql

我有一个查询,如果members表中不存在mem_id,则从swipes表中选择用户。查询如下:

SELECT members.* FROM members
WHERE NOT EXISTS (SELECT * FROM swipes WHERE (mem_id IN (swp_by, swp_to) AND :mem IN (swp_by)))

上面的查询完成了我一半的工作。但是,我想在这里添加更多其他条件。在swipes表中,有两个字段,即swp_typeswp_status。这里的swp_type具有ENUMleft, right, top,表示刷卡的卡是向左,向右或顶部(例如火种),并且swp_status也具有ENUM值{{1 }}指出所请求的朋友是否仍处于请求状态,是否被接受,拒绝或在匹配不匹配之后被拒绝。现在,我想修改上面的查询,以便它在条件中接受这两个表并基于它们返回结果。

让我们举个例子:

说,有两个用户1和2。requested, accepted, declined, unmatched表中现在没有记录,因此用户1和2可以看到对方。

现在,假设用户1向左滑动用户2,则:

swipes

对于上述数据,用户1向左滑动用户2(这意味着用户1不想与用户2匹配),因此他们将不再能够看到对方。

现在,假设用户1的权限为RIGHT或TOP轻扫了用户2,那么:

swp_by: 1, swp_to: 2, swp_type: left, swp_status: requested

对于上述数据,用户1不再可以看到用户2,但是用户2可以看到用户1,因为此处的swp_by: 1, swp_to: 2, swp_type: right/top, swp_status: requested 是正确的,而swp_typeswp_status

现在说,对于上述数据requested不是swp_status,但除了requested以外,其他任何人都说(接受/拒绝),那么两个用户将无法再看到对方再次。这就是我想作为条件添加到当前查询中的内容。

我当前的查询通过考虑requestedswipes显示swp_by表中不存在的成员来完成一半的工作。我想如上所述为swp_toswp_type添加条件。

我尝试了什么?

我尝试了以下操作,但最终结果很奇怪。当根据数据返回所有成员时,它仅应返回带有swp_status mem_id的成员,因为相对于用户1和用户8而言,它在滑动表中不存在12right以及用户requested依次为15top

requested

因此,我认为这不是我必须放置条件的方式。

在这里拨弄:DB FIDDLE

1 个答案:

答案 0 :(得分:1)

我在这里四处走走,因为我承认按照您的解释我经历了一段非常艰难的时期。最后,我不知道您是在描述信用卡处理,约会服务还是其他。因此,您可能不得不根据我可能会有的任何误解来“调整” SQL。

为了更好地理解我的SQL,我采用了原始SQL:

SELECT members.* FROM members
WHERE NOT EXISTS (SELECT * FROM swipes WHERE (mem_id IN (swp_by, swp_to) AND 1 IN (swp_by)))

并将其重铸为我认为等同的内容,并以此作为起点:

SELECT members.* FROM members
WHERE mem_id <> 1
AND NOT EXISTS (
  SELECT * FROM swipes WHERE mem_id = swp_to AND swp_by = 1
)

我最终得到:

SELECT * from members
WHERE mem_id <> 1
AND NOT EXISTS (
  SELECT * FROM swipes WHERE
      members.mem_id = swp_by and 1 = swp_to OR
      members.mem_id = swp_to and 1 = swp_by
)
UNION
SELECT * FROM members
WHERE mem_id <> 1
AND EXISTS (
  SELECT * FROM swipes WHERE swp_by = members.mem_id AND swp_to = 1
  AND swp_type <> 'left' AND swp_status = 'requested'
)

这是一个工会。第一部分是:

SELECT * from members
WHERE mem_id <> 1
AND NOT EXISTS (
  SELECT * FROM swipes WHERE
      members.mem_id = swp_by and 1 = swp_to OR
      members.mem_id = swp_to and 1 = swp_by
)

这是在尝试选择“与用户1相关的滑动表中不存在的所有行”,这些行将与示例数据mem_id 8一起使用。现在也许应该只检查swp_by=1swp_to=8,而不要检查swp_by=8swp_to=1(反之亦然)。如果是这样,您可以进行调整。

第二个并集添加具有相应滑动(swp_by设置为mem_id)且其中swp_type不等于'left'swp_status的行等于'requested',其中swp_to等于1。我已经根据您的样本数据和您希望返回的行使用了此条件:

SELECT * FROM members
WHERE mem_id <> 1
AND EXISTS (
  SELECT * FROM swipes WHERE swp_by = members.mem_id AND swp_to = 1
  AND swp_type <> 'left' AND swp_status = 'requested'
)

如果SQL并不是您所需要的,我认为只需要进行一点调整即可。

See Db-Fiddle

上述操作也可以使用内部和外部连接来实现:

SELECT members.* from members LEFT JOIN swipes ON
  mem_id = swp_by AND 1 = swp_to OR
  mem_id = swp_to and 1 = swp_by
WHERE mem_id <> 1 AND swp_id is NULL
UNION
SELECT DISTINCT members.* FROM members JOIN swipes ON
  mem_id = swp_by AND
  swp_to = 1 AND
  swp_type <> 'left' AND
  swp_status = 'requested'
WHERE mem_id <> 1

DB-Fiddle

从以上内容可以看出,有机会删除联合:

SELECT DISTINCT members.* from members LEFT JOIN swipes ON
  mem_id = swp_by AND 1 = swp_to OR
  mem_id = swp_to AND 1 = swp_by
WHERE mem_id <> 1 AND
  swp_id is NULL OR (
    mem_id = swp_by AND
    swp_to = 1 AND  
    swp_type <> 'left' AND
    swp_status = 'requested'
  )
ORDER BY mem_id

DB-Fiddle