2011-05-18 103 views
1

我试图返回具有重复值的最大限定数量的未分组值的列表。我已经恢复成这样值的列表:选择重复/重复值,未分组

select TagDirID from tags where id = '550' 

的结果将是:

9508 
10382 
10672 
65454 
65454 
65454 
65454 

正如你可以看到有是65454. 4次的重复,我想返回有一个列表用户为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
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排序功能。

+0

TagID是主键。 – 2011-05-18 16:30:13

+0

@Brad Stewart - 好的。已调整。 – Thomas 2011-05-18 16:42:59

+0

@ thomas。太复杂了,不是吗?请你解释或提交任何链接。在上查询'AND t2.TagID一件事 diEcho 2011-05-18 17:03:47

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; 

那么结果将是由你有什么有点不同(不重复的项目,而是一个项目,复制数量),但我认为它会做。

+0

'distinct'可能只返回单列每个'tagDirId' – diEcho 2011-05-18 16:22:35

+0

是,每个tagDirId,但与其他列计数。 – Gabriel 2011-05-18 16:26:00