2010-09-26 100 views
0

我正在使用以下查詢從子組中的最小日期差異(由ID1,ID2對定義)中提取隨機行。將相同的排名賦予與mysql中具有相同屬性的行

它不起作用,因爲按日期差異對行排序的步驟僅將第一個觀察值賦予rank = 1(即使第二個觀察者具有相同的日期差異並且也應該接收等級= 1)。

不知怎的,我需要改變WHEN子句類似...

CASE 
WHEN @id1 = t.id1 AND @id2 = t.id2 AND @diff != diff THEN @rownum := @rownum + 1 
ELSE @rownum := 1 

但是當我這樣做,它沒有找到差異場...

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, 
      x.rk 
    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; 

我米粘貼SQL轉儲

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'); 

這個版本實際上是非常接近我所需要的

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.*, 
     @rownum := CASE 
      WHEN @id1 = t.id1 AND @id2 = t.id2 AND @diff != diff THEN @rownum + 1 

      ELSE 1 
      END AS rk, 
     @id1 := t.id1, 
     @id2 := t.id2, 
     @diff := t.diff 
    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 
     FROM temp3 t 
     ORDER BY t.id1, t.id2, diff, RAND() 
    ) t, 
    ( SELECT @rownum := 0, @id1 := null, @id2 := null, @diff := null) r 
) x 
WHERE x.rk = 1; 
+0

@ OMG-小馬@OMGPonies我認爲解決的辦法是正確的排名也有同樣的差異,但不讀作第一排排(即他們應該得到RANK = 1呢!)。我試過了CASE WHEN @ id1 = t.id1 AND @ id2 = t.id2 AND @diff!= diff THEN @rownum:= @rownum + 1 ELSE @rownum:= 1 – Cat 2010-09-26 21:12:44

+0

你想返回一行 - 如果你排列關係,然後隨機把第一個和第一個唯一的排名委派給他們,這有什麼關係?相比之下,你的方法是不必要的複雜。 – 2010-09-26 21:14:01

+0

在那些有最小日期差異的人中,我需要每次隨機選擇一個。在上面的例子中,ID3 = 88和ID3 = 44應該有相同的機會出現在結果表中,而ID3 = 55不應該出現,因爲在它的組中(ID1 = 1,ID2 = 2)它有更高的日期差異比ID3 = 57。你的幫助真的很感謝! @OMGPonies – Cat 2010-09-26 21:18:18

回答

0

這是一個工作解決方案。感謝@OMG小馬爲您提供幫助。

SELECT 
x.id1, 
x.id2, 
x.YEAR, 
x.MMDD, 
x.id3, 
x.id3_YEAR, 
x.id3_MMDD 
FROM 
(SELECT 
    t.*, 
    @rownum := CASE 
    WHEN @id1 = t.id1 AND @id2 = t.id2 THEN @rownum + 1 
    ELSE 1 
    END AS rk, 
    @id1 := t.id1, 
    @id2 := t.id2 
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 
    FROM temp3 t 
    ORDER BY t.id1, t.id2, diff, RAND() 
) t, 
(SELECT @rownum := 0, @id1 := null, @id2 := null) r 
) x 
WHERE x.rk = 1;