使用尽可能少的相邻值排列数组

时间:2011-10-15 08:52:23

标签: sql algorithm sorting

使用这样的数组:

[google, google, yahoo, yahoo, yahoo, msn, msn, msn, google]

使用尽可能少的相邻值来排列它的最佳方法是什么? 目标是获得这样的东西,例如:

[google, msn, yahoo, google, yahoo, msn, yahoo, msn, google]

更好的是确保任何相似值尽可能相互之间的算法。

更好的方法是直接在SQL中完成。

我正在为我正在制作的发送简报的脚本这样做,我想避免一次发送太多电子邮件到同一个域。

[edit]我正在使用MySQL

2 个答案:

答案 0 :(得分:4)

使用SQL Server 2005及更高版本,您可以利用ROW_NUMBER功能

  • 为每个项目添加行号,在网站名称上进行分区。
  • 从此子查询中选择
  • 在rownumber和名称上订购结果。

你的要求应尽可能远离彼此,但总而言之,这就足够了。

SQL语句

SELECT  Site
FROM    (
            SELECT  Site, o = ROW_NUMBER() OVER (PARTITION BY Site ORDER BY Site)
            FROM    q
        ) q
ORDER BY                
        o, Site

结果

  

google msn yahoo google msn yahoo google msn yahoo

测试脚本

;WITH q ([site])AS (
    SELECT 'google'
    UNION ALL SELECT 'google'
    UNION ALL SELECT 'yahoo'
    UNION ALL SELECT 'yahoo'
    UNION ALL SELECT 'yahoo'
    UNION ALL SELECT 'msn'
    UNION ALL SELECT 'msn'
    UNION ALL SELECT 'msn'
    UNION ALL SELECT 'google'   
)
SELECT  Site
FROM    (
            SELECT  Site, o = ROW_NUMBER() OVER (PARTITION BY Site ORDER BY Site)
            FROM    q
        ) q
ORDER BY                
        o, Site

答案 1 :(得分:0)

谢谢Lieven,我调整了你对MySQL的回答,它运作得很好:

select *
from (
    select
      @i := if(@last_name != t2.name, 1, @i + 1) as row_number,
      @last_name := t2.name as `name`
    from
      site t2,
      (select @i := 0) vt1,
      (select @last_name := null) vt2
    order by t2.name
) t1
order by t1.row_number, t1.name
;

给出:

+------------+--------+
| row_number | name   |
+------------+--------+
|          1 | google |
|          1 | msn    |
|          1 | yahoo  |
|          2 | google |
|          2 | msn    |
|          2 | yahoo  |
|          3 | google |
|          3 | msn    |
|          3 | yahoo  |
+------------+--------+