SQL - 如何列出关系中的所有元组,使元组1大于元组2

时间:2014-10-06 17:17:29

标签: sql database

假设我只与1列“Value(INT)”有关系,其值按降序排列。

+----------+
+  VALUE   +
+----------+
+    10    +
+    9     +
+    8     +
+    7     +
....

如何列出包含两个元组的所有组合,以使第一个元组大于第二个元组

注意:它可能存在两个具有相同值的元组

所需的输出应如下:(10,9)(10,8)(9,8),(9,7)(8,7)

2 个答案:

答案 0 :(得分:3)

您可以在同一张桌子上进行交叉连接。

SELECT t1.VALUE AS VALUE1, t2.VALUE AS VALUE2
FROM thing t1 JOIN thing t2 ON (t1.VALUE != t2.VALUE AND t1.VALUE > t2.VALUE)

答案 1 :(得分:0)

据我所知,单个元组在结果集的左侧只能出现两次,对不对?这就是为什么没有(10,7)? 然后你需要计算行号。

select t1.value, t2.value
from
(
    select t.value, row_number(order by t.value) as rnum
    from table t
) t1 inner join
(
    select t.value, row_number(order by t.value) as rnum
    from table t
) t2 on t1.value > t2.value and t1.rnum < t2.rnum + 2

此查询的性能非常差,但我不知道您使用的是哪个数据库 - 我使用了MS SQL row_number函数。

另一个想法: 如果您使用的是SQL Server 2012+,并且您对本文开头提出的问题的回答是肯定的,您可以使用:

select t.value, lead(t.value,1,0) over(order by t.value desc) as lead1
    lead(t.value,2,0) over(order by t.value desc) as lead2
from table t

如果没有“lead”元组,你可能需要处理0(defulat值)。我不确定这种形式的输出是否可以接受。

在这里,您可以使用光标解决方案:

DECLARE @result TABLE
(
    value1 int,
    value2 int
);
DECLARE
    @value int,
    @lag1 int,
    @lag2 int

DECLARE c CURSOR LOCAL STATIC FORWARD_ONLY READ_ONLY
FOR
SELECT value
FROM table
ORDER BY value desc
OPEN c;

FETCH NEXT FROM c INTO @lag2;
FETCH NEXT FROM c INTO @lag1;

FETCH NEXT FROM c INTO @value;

WHILE @@FETCH_STATUS = 0
BEGIN

    INSERT @result(value1, value2) SELECT @lag2, @lag1
    INSERT @result(value1, value2) SELECT @lag2, @value

    SET @lag2 = @lag1
    SET @lag1 = @value

    FETCH NEXT FROM c INTO @value

END
CLOSE c;

同样,我使用了MS SQL语法。如果你写下你希望如何处理重复项,我可以更新解决方案。