选择重复/重复值,未分组

时间:2011-05-18 16:03:35

标签: mysql duplicates

我正在尝试返回具有最大定义重复值数的未分组值列表。我有一个检索到的值列表:

select TagDirID from tags where id = '550'

结果将是:

9508
10382
10672
65454
65454
65454
65454

正如您所看到的,有4个重复的65454.我想返回一个列表,该列表具有用户定义的TagDirID最大重复次数。例如,仅选择3个或更少的重复:

9508
10382
10672
65454
65454
65454

我发现的所有方法都返回一个分组列表,我想保留各个项目。这可以在查询中完成吗?有一个主键,TagID。

编辑:这样做是为项目选择所有标签,id ='550'。因为它是用户内容,有时人们会多次标记相同的内容,而我正在尝试减少我显示的重复内容。

编辑2:所以,虽然接受的答案对我有用,但我发现它对于我需要的东西来说有点太慢了所以我想出了一个php解决方案:

function get_tags($ID = '', $tags_to_keep = 3)
{   
    // Select all tags.
    $query = "select TagDirID, Tag from tags where id = '$ID'";

    $tags_result = mysql_query($query); 

    $num_results = mysql_num_rows($tags_result);

    for ($i=0; $i<$num_results; $i++)
    {
        //Get tag topics
        $tags_row = mysql_fetch_array($tags_result);

        //build array of items already found with counts
        $tags_count = array_count_values($tags_filter);

        //if number of tags already found($tags_count/$tags_filter) is less than or equal to tags_to_keep then add to filtered array and return array.
        if($tags_count[$tags_row['TagDirID']] <= $tags_to_keep)
        {
            $tags_filter[$i] = $tags_row['TagDirID'];
            $tags[$i] = $tags_row['Tag'];
        }           
    }

    return $tags;
}

2 个答案:

答案 0 :(得分:2)

Select TagID, TagDirID
From    (
        Select T1.TagID, T1.TagDirID
             , (Select Count(*)
                From tags As T2
                Where T2.TagDirID = T1.TagDirID
                    And T2.TagID < T1.TagID) As Rnk
        Where T1.id = '550'
        From tags As T1
        ) As T
Where T.Rnk < 3

编写同一查询的另一种方法:

Select TagID, TagDirID
From    (
        Select T1.TagID, T1.TagDirID, Count( T2.TagID ) As Rnk
        From tags As T1
            Left Join tags As T2
                On T2.TagDirID = T1.TagDirID
                    And T2.TagID < T1.TagID
        Where T1.id = '550'
        Group By T1.TagID, T1.TagDirID
        ) As T
Where T.Rnk < 3

这里的方法是模仿排名函数,该函数将为每个TagDirID分组排序行。因此,上述两个解决方案中的任何一个中的内部查询都应该为您提供如下内容:

TagID | TagDirID | Rnk
1     | 9508     | 0
2     | 10382    | 0
3     | 10672    | 0
4     | 65454    | 0
5     | 65454    | 1
6     | 65454    | 2
7     | 65454    | 3

对于每个分组中编号的行,我们现在可以过滤掉我们的结果,这样我们只能获得任何给定组中的最大行数。 ISO / ANSI解决方案是使用MySQL尚不支持的ROW_NUMBER排名功能。

答案 1 :(得分:0)

由于重复值全部相等,您可以查询不同项目的重复次数。对于3件或更少的东西,它会是这样的:

SELECT T.tdid, T.cnt
FROM ( 
      SELECT distinct(TagDirID) as tdid, 
             (SELECT COUNT(*) FROM tags WHERE id = tdid) as cnt 
      FROM tags
) as T
WHERE T.tdid = '550' AND T.cnt < 3;

所以结果会与你的结果略有不同(不是重复的项目,而是一个项目和重复的数量),但我认为它会这样做。