2011-01-28 8 views
1

これは私のSQLクエリです.2つの列が「下位」と「上位」の単一の結果行を生成します。 Rankableテーブルの行の主キー( "id")に対応します。このSQLクエリは、2つのフィールドではなく2つの行を出力するようにするにはどうすればよいですか?

クエリの目的は、ランク付け可能な行のランダムなペアを選択することです。これは、以前のすべてのペアを含む比較テーブルには存在しません。

しかし、私が必要とするのは、このクエリでは、ランク付け可能IDだけでなく、単一行のフィールドとして2つのRankableを行として返すことです。

これは、現在のクエリです:

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

あなたのmysqlタグに気付かなかった...私の答えは20秒後に削除されました。それを投稿するが、いくつかの忍者はまだdownvoteを持っていた:D – Matthew

+0

@Matthew PK私はチェックし、MySQLがそれを持っていないことがわかるまで、 – troutinator

答えて

2

私はすべて取得するには、テーブルに参加するには

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 

。これMySQLがハッキング呼び出します他の列:

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

ありがとうございます。 – sanity

+0

私は答えを出しましたが、フロントエンドを使ってみることを心からお勧めします。 2列または2行 – RichardTheKiwi

+0

「フロントエンド」とはどういう意味ですか?なぜなら、2行にする必要があるのは、Java Persistence 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

関連する問題