2011-01-28 21 views
1

這是我的SQL查詢,它產生一個單獨的結果行,有兩列「下」和「更高」。這些對應於Rankable表中行的主鍵(「id」)。如何獲得此SQL查詢以輸出兩行而不是兩個字段?

該查詢的目的是選擇一個隨機的一對Rankable行,它不在比較表中(它包含所有先前的對)。

但是,我需要的是這個查詢將兩個Rankable作爲行返回,而不僅僅是單行中的可排序ID作爲字段。

這是當前查詢:

SELECT a.id AS lower, b.id AS higher 
FROM Rankable a 
INNER JOIN Rankable b on a.id < b.id 
WHERE 
    a.category_id = ? AND b.category_id = ? 
    AND NOT EXISTS (
    SELECT * 
    FROM Comparison c 
    WHERE c.lower_id in (a.id, b.id)) 
    AND NOT EXISTS (
    SELECT * 
    FROM Comparison c 
    WHERE c.higher_id IN (a.id, b.id)) 
ORDER BY a.id * rand() 
LIMIT 1; 
+1

對不起'PIVOT'建議..我沒有注意到你的mysql標記...刪除我的答案像20秒後r發佈它,但一些忍者仍然得到一個downvote在:D – Matthew

+0

@Mthethew PK我幾乎發佈解決方案使用'WITH'直到我檢查,發現在MySQL沒有它。 – troutinator

回答

2

我稱之爲MySQL的黑客..

select @a as one 
from 
(

    SELECT @a := a.id, @b := b.id 
    FROM Rankable a 
    INNER JOIN Rankable b on a.id < b.id 
    WHERE 
     a.category_id = ? AND b.category_id = ? 
     AND NOT EXISTS (
     SELECT * 
     FROM Comparison c 
     WHERE c.lower_id in (a.id, b.id)) 
     AND NOT EXISTS (
     SELECT * 
     FROM Comparison c 
     WHERE c.higher_id IN (a.id, b.id)) 
    ORDER BY a.id * rand() 
    LIMIT 1 
) SQ 
union all 
select @b 

要加入到表來獲取所有其他列:

select Rankable.* 
from 
(
    select 1 as Sort, @a as one 
    from 
    (

     SELECT @a := a.id, @b := b.id 
     FROM Rankable a 
     INNER JOIN Rankable b on a.id < b.id 
     WHERE 
      a.category_id = ? AND b.category_id = ? 
      AND NOT EXISTS (
      SELECT * 
      FROM Comparison c 
      WHERE c.lower_id in (a.id, b.id)) 
      AND NOT EXISTS (
      SELECT * 
      FROM Comparison c 
      WHERE c.higher_id IN (a.id, b.id)) 
     ORDER BY a.id * rand() 
     LIMIT 1 
    ) SQ 
    union all 
    select 2, @b 
) X 
INNER JOIN Rankable ON Rankable.Id = X.one 
ORDER BY X.Sort 
+0

謝謝,我期待着嘗試它。呃,它是一個恥辱你不能做這樣的事情沒有hackery。讓你想知道SQL是否是「正確的方式」 – sanity

+0

雖然我給出了答案,誠懇地建議你看看只使用前端,這是微不足道的處理是否爲2列或2行 – RichardTheKiwi

+0

你是什麼意思的「前端」?我需要它作爲兩行的原因是,它與Java持久性API很好。 – sanity

0

創建2個查詢一個較低和一個較高的級別,然後聯合在一起。 用等級創建一個靜態列來標識哪個是哪個。 「高」或「秩

+0

這聽起來頗具挑戰性,因爲我們需要驗證特定對不在比較表中,因此我們一次都需要它們。 – sanity

0

不漂亮較低,但我認爲這將工作:

SELECT * FROM Rankable JOIN (
    SELECT a.id AS lower, b.id AS higher 
    FROM Rankable a 
    INNER JOIN Rankable b on a.id < b.id 
    WHERE  
    a.category_id = ? AND b.category_id = ? 
    AND NOT EXISTS (
     SELECT * 
     FROM Comparison c 
     WHERE c.lower_id in (a.id, b.id) 
    ) 
    AND NOT EXISTS (
     SELECT * 
     FROM Comparison c 
     WHERE c.higher_id IN (a.id, b.id) 
    ) 
    ORDER BY a.id * rand() 
    ) AS rank_them 
ON (Rankable.id = rank_them.higher OR Rankable.id = rank_them.lower) 
+0

我試過了,但它似乎沒有工作,它返回了12行(Rankable中有4行,沒有任何比較):-( – sanity

相關問題