简体   繁体   English

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

[英]MySQL Query to find row duplicates based on condition with limit

I have two tables: 我有两张桌子:

Members:

id     username    


Trips:

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

I can do a query like this: 我可以这样做一个查询:

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

Which CAN give results like this: 哪个可以得到这样的结果:

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

My goal is to know if the member's last three trips all had a flag_status = "YES", if any of the three != "YES", then I don't want it to count. 我的目标是知道会员的最后三次旅行是否都有一个flag_status =“YES”,如果三个中的任何一个!=“是”,那么我不想让它算在内。

I also want to be able to remove the WHERE Trip.member_id = 1711 clause, and have it run for all my members, and give me the total number of members whose last 3 trips all have flag_status = "YES" 我还希望能够删除WHERE Trip.member_id = 1711子句,让它为所有成员运行,并给我最后3次旅行的所有成员总数flag_status =“YES”

Any ideas? 有任何想法吗?

Thanks! 谢谢!

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

In that sqlfiddle, when the correct query i'm seeking runs, I should see results such as: 在那个sqlfiddle中,当我正在寻找的正确查询运行时,我应该看到如下结果:

 COUNT(Member.id)
        2

The two members that should qualify are members 1 and 3. Member 5 fails because one of his trips has flag_status = "NO" 应该符合资格的两个成员是成员1和3.成员5失败,因为他的一次旅行有flag_status =“NO”

You could use GROUP_CONCAT function, to obtain a list of all of the status ordered by id in ascending order: 您可以使用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%'

and then using SUBSTRING_INDEX you can extract only the last three status flags, and exclude those that contains a NO. 然后使用SUBSTRING_INDEX,您只能提取最后三个状态标志,并排除那些包含NO的状态标志。 Please see fiddle here . 请看这里的小提琴。 I'm assuming that all of your rows are ordered by ID, but if you have a created date you should better use: 我假设您的所有行都按ID排序,但如果您有创建日期,则最好使用:

GROUP_CONCAT(flag_status ORDER BY created DESC) as status

as Raymond suggested. 正如雷蒙德所说。 Then, you could also return just the count of the rows returned using something like: 然后,您还可以使用以下内容返回返回行的计数:

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

Although I like the simplicity of fthiella's solution, I just can't think of a solution that depends so much on data representation. 虽然我喜欢fthiella解决方案的简单性,但我想不出一个非常依赖于数据表示的解决方案。 In order not to depend on it you can do something like this: 为了不依赖它你可以做这样的事情:

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

Fiddle here . 在这里小提琴 Note I've slightly modified the fiddle to remove one of the users. 注意我稍微修改了小提琴以删除其中一个用户。

The process basically ranks the trips for each of the members based on their id desc and then only keeps the last 3 of them. 该过程基本上根据他们的id desc对每个成员的旅行进行id desc ,然后只保留最后3个。 Then it makes sure that none of the fetched trips has a NO in the flag_status. 然后它确保所有提取的行程都NO在flag_status中有NO FInally all the matching meembers are counted. 最后计算所有匹配的会员。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM