MySQL Query根据带有限制的条件查找行重复项

时间:2013-11-09 15:42:54

标签: mysql duplicates limit conditional-statements rows

我有两张桌子:

Members:

id     username    


Trips:

id    member_id     flag_status         created
                  ("YES" or "NO")

我可以这样做一个查询:

SELECT 
  Trip.id, Trip.member_id, Trip.flag_status
FROM  
  trips Trip
WHERE   
  Trip.member_id = 1711
ORDER BY
  Trip.created DESC
LIMIT
  3

哪个可以给出这样的结果:

id       member_id     flag_status
8        1711          YES
9        1711          YES
10       1711          YES

我的目标是知道会员的最后三次旅行是否都有一个flag_status =“YES”,如果三个中的任何一个!=“是”,那么我不想让它算在内。

我还希望能够删除WHERE Trip.member_id = 1711子句,让它为所有成员运行,并给我最后3次旅行都有flag_status =“YES”的成员总数

有什么想法吗?

谢谢!

http://sqlfiddle.com/#!2/28b2d

在那个sqlfiddle中,当我正在寻找的正确查询运行时,我应该看到如下结果:

 COUNT(Member.id)
        2

应该符合资格的两名成员是成员1和3.成员5失败,因为他的一次旅行有flag_status =“NO”

2 个答案:

答案 0 :(得分:2)

您可以使用GROUP_CONCAT函数,以升序获取按ID排序的所有状态的列表:

SELECT
  member_id,
  GROUP_CONCAT(flag_status ORDER BY id DESC) as status
FROM
  trips
GROUP BY
  member_id
HAVING
  SUBSTRING_INDEX(status, ',', 3) NOT LIKE '%NO%'

然后使用SUBSTRING_INDEX,您只能提取最后三个状态标志,并排除那些包含NO的状态标志。请参阅小提琴here。我假设您的所有行都按ID排序,但如果您有创建日期,则最好使用:

GROUP_CONCAT(flag_status ORDER BY created DESC) as status
正如雷蒙德建议的那样。然后,您还可以使用以下内容返回返回行的计数:

SELECT COUNT(*)
FROM (
  ...the query above...
) as q

答案 1 :(得分:2)

虽然我喜欢fthiella解决方案的简单性,但我想不出一个在很大程度上依赖于数据表示的解决方案。为了不依赖它,你可以做这样的事情:

SELECT COUNT(*) FROM (
  SELECT member_id FROM (
    SELECT
      flag_status,
      @flag_index := IF(member_id = @member, @flag_index + 1, 1) flag_index,
      @member := member_id member_id
    FROM trips, (SELECT @member := 0, @flag_index := 1) init
    ORDER BY member_id, id DESC
  ) x
  WHERE flag_index <= 3
  GROUP BY member_id
  HAVING SUM(flag_status = 'NO') = 0
) x

小提琴here。注意我稍微修改了小提琴以删除其中一个用户。

该过程基本上根据每个成员id desc对每个成员的行程进行排名,然后仅保留最后3个成员。然后它确保所提取的行程中没有一个在flag_status中有NO。最后计算所有匹配的会员。