如何让这个SQL查询输出两行,而不是两个字段?

时间:2011-01-28 23:05:41

标签: mysql

这是我的SQL查询,它生成一个结果行,有两列“lower”和“higher”。这些对应于Rankable表中行的主键(“id”)。

查询的目的是选择一对随机行,这些行在比较表中不存在(包含所有先前的对)。

然而,我需要的是,此查询将两个Rankables作为行返回,而不仅仅将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;

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

为较低级别创建2个查询,为较高级别创建1个查询,然后将它们组合在一起。 创建一个具有等级的静态列,以标识哪个是哪个。 '较高'或'较低等级

答案 2 :(得分: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)