2010-09-26 77 views
1

我使用以下查询从子集中为每个ID1-ID2对在时间上具有最小距离(YEAR和MMDD字段)的记录随机绘制一行, 。修复mysql查询以返回子组内的随机行

CREATE TABLE temp4 AS 
    SELECT * 
     FROM temp3 
    GROUP BY ID1, ID2 
    ORDER BY DATEDIFF(CONCAT(YEAR,'-',LEFT(MMDD,2),'-',RIGHT(MMDD,2)), CONCAT(ID3_YEAR,'-',LEFT(ID3_MMDD,2),'-',RIGHT(ID3_MMDD,2))) ASC, RAND() 
    LIMIT 0, 1; 

从前面的问题我已经张贴在这里,这是表的样子

ID1 ID2 YEAR MMDD ID3 YEAR_ID3 MMDD_ID3 
--------------------------------------- 
1 2 1991 0821 55 1991  0822  
1 2 1991 0821 57 1991  0822  
1 2 1991 0821 88 1992  0101 
1 3 1990 0131 89 2000  0202  
1 3 1990 0131 89 2001  0102 

FOR EACH ID1,ID2对,我需要

选择ID3

时间上的最小距离(YEAR字段和MMDD字段,即我需要比较YEAR和MMDD与YEAR_ID3和MMDD_ID3)

如果多于一个ID3满足最低要求(即,他们都有相同的YEAR_ID3和MMDD_ID3),我需要随机选择一个。

在上面的例子中,查询应该返回

1,2,1991,0821,55 (OR 1,2,1991,0821,57 - ACCORDING TO THE RANDOM DRAW) 

1,3,1990,0131,89 

我上面粘贴只返回一行ONE ... :(

莫名其妙地出现了一个很好的解决方案在下面评论区张贴OMG ......但它消失了?!?!?

我在这里把它粘贴

DROP TABLE IF EXISTS temp4; 
CREATE TABLE temp4 AS 
SELECT x.id1, 
     x.id2, 
     x.YEAR, 
     x.MMDD, 
     x.id3, 
     x.id3_YEAR, 
     x.id3_MMDD 
FROM (SELECT t.*, 
       ABS(DATEDIFF(CONCAT(CAST(t.id3_YEAR AS CHAR(4)),'-', LEFT(t.id3_MMDD,2),'-',RIGHT(t.id3_MMDD,2)), 
         CONCAT(CAST(t.YEAR AS CHAR(4)),'-', LEFT(t.MMDD,2),'-',RIGHT(t.MMDD,2)))) AS diff, 
       CASE 
       WHEN @id1 = t.id1 AND @id2 = t.id2 THEN @rownum := @rownum + 1 
       ELSE @rownum := 1 
       END AS rk, 
       @id1 := t.id1, 
       @id2 := t.id2 
      FROM temp3 t 
      JOIN (SELECT @rownum := 0, @id1 := 0, @id2 := 0) r 
     ORDER BY t.id1, t.id2, diff, RAND()) x 
WHERE x.rk = 1; 

我在这里粘贴一个测试表

DROP TABLE IF EXISTS `temp3`; 
CREATE TABLE IF NOT EXISTS `temp3` (
    `id1` char(7) NOT NULL, 
    `id2` char(7) NOT NULL, 
    `YEAR` year(4) NOT NULL, 
    `MMDD` char(4) NOT NULL, 
    `id3` char(7) NOT NULL, 
    `id3_YEAR` year(4) NOT NULL, 
    `id3_MMDD` char(4) NOT NULL 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 


INSERT INTO `temp3` VALUES('1', '2', 1992, '0107', '55', 1991, '0528'); 
INSERT INTO `temp3` VALUES('1', '2', 1992, '0107', '57', 1991, '0701'); 
INSERT INTO `temp3` VALUES('1', '3', 1992, '0107', '88', 2000, '0101'); 
INSERT INTO `temp3` VALUES('1', '3', 1992, '0107', '44', 2000, '0101'); 
+0

是否有原因,为什么你不使用'DATE'字段而不是'YEAR'和'MMDD'在这里? – Hammerite 2010-09-26 01:24:05

+0

是的,这就是数据来的方式(表格非常庞大 - 6M行)。如果你认为它很有用,我很乐意为你添加一个新的专栏... – Cat 2010-09-26 01:25:27

+0

OMG小马,你的答案消失了吗? – Cat 2010-09-26 04:38:07

回答

0

的SQL转储的常用方法从查询提取随机结果被

SELECT [] FROM表ORDER BY RAND( )LIMIT []

+0

我没有更好的答案(我不使用MySQL太多),但有很多博客说这是一个非常昂贵的方法。 – egrunin 2010-09-26 04:45:26

+0

是的,但不是针对具体问题,只需要打破平局。 – 2010-09-26 21:28:43