2013-11-09 50 views
1

条件去找寻行重复我有两个表:MySQL查询基于与限制

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”,如果有三个!=“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”

+0

在SQLfiddle上放置一个带有multile member_ids的示例数据表。 –

+0

“我的目标是要知道成员的最后三次旅行是否都有flag_status =”YES“,如果有三个!=”YES“,那么我不想让它算。“你的意思是,MySQL应该总是检查基于日期的最后记录(DESC)并在flag_status =”Yes“上过滤这三条记录,或者我误解了该部分。 –

+0

member_id是成员表的外键, – user2278120

回答

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 
+0

谢谢fthiella!通过修改你的一行到:SUBSTRING_INDEX(status,' ,',3)=“是,是,是”我能够让它按照我的需要运作! – user2278120

+0

@ user2278120欢迎您:)是的,它几乎是相同的,使用“YES,YES,YES”,您将返回所有至少有三个状态标志的成员,使用NOT LIKE'%NO%',它会选择记录只有一个或两个“是” – fthiella

+0

不明白为什么这被标记为正确的,因为这是假设在身份证上,而不是基于创建(主题起始者想要的,所以这是由 机会的结果是正确的,因为最有可能关闭AUTO_INCREMENT ID ..)。应该是'GROUP_CONCAT(flag_status ORDER BY创建DESC)作为状态' –

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。最后,所有匹配的成员都被计算在内。

+0

嗨Mosty ,感谢您的回复,但是我无法理解,即使有您的解释。你可能可以更深入地解释一下使用mySQL变量的新手吗?我确实想要对我的实际分贝运行这个,看看它是否比fthiella的解决方案更快,并且根据哪一个更快,我将选择合适的答案作为最佳答案。 – user2278120

+0

如果您需要更多关于UDV的信息,您应该阅读[this one]这样的教程(http://my.safaribooksonline.com/book/databases/mysql/9780596101718/query-performance-optimization/user-defined_variables) –

+0

您。 :)我会检查出来。 – user2278120