0

我有一张桌子:

Type | Value
1    | '1test1'
2    | '2test1'
2    | '2test2'
2    | '2test3'

我想得到一个包含一对的结果,其中每种类型的每个条目至少使用一次,但不超过要求。

从上面的示例表中,我想要以下结果:

1test1 - 2test1
1test1 - 2test2
1test1 - 2test3

如果表是:

Type | Value
1    | '1test1'
1    | '1test2'
1    | '1test3'
2    | '2test1'
2    | '2test2'
2    | '2test3'

我想要以下结果:

1test1 - 2test1
1test2 - 2test2
1test3 - 2test3

如果表是:

Type | Value
1    | '1test1'
1    | '1test2'
2    | '2test1'
2    | '2test2'
2    | '2test3'

我想要以下结果:

'1test1' - '2test1'
'1test2' - '2test2'
'1test1' - '2test3'
'1test1' - '2test1'
'1test2' - '2test2'
'1test1' - '2test3'

我希望每种类型与同一类型中的其他值一样重复。类型中的值不应比同一类型中的其他值更频繁地重复。

使用 SQL 或存储过程,或使用一系列 SQL 语句,最优雅的方法是什么?

4

3 回答 3

1

这是一个有点做作的答案,但我想它适合这个问题:

create table stuff( idx tinyint unsigned, val varchar(50));
insert into stuff( idx, val ) values ( 1, '1val1'), (1, '1val2'), (2,'2val1'),    
   (2,'2val2'), (2, '2val3');


SELECT s0.val v0, s1.val v1 FROM stuff s0 
  JOIN stuff s1 ON s0.idx != s1.idx 
  where s0.idx = 1;

这是一个小提琴

于 2013-03-09T13:22:01.767 回答
1

这是你想要的吗

SELECT 
    s.val AS One,
    r.val AS Second
FROM stuff AS s
LEFT OUTER JOIN (SELECT * FROM stuff WHERE idx = 2) AS r ON r.idx <> s.idx
WHERE s.idx = 1

SQL 小提琴演示

输出 :

One     |   Second
--------------------
1val1   |   2val1
1val1   |   2val2
1val1   |   2val3
1val2   |   2val1
1val2   |   2val2
1val2   |   2val3
于 2013-03-09T13:25:41.530 回答
1

当每种类型的行数不同时,这有点容易,但是一旦这样做,它就会变得有些棘手。

所以我想出了这个:

CREATE PROCEDURE test()
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE type1, type2 INT;
  DECLARE value1, value2 VARCHAR(5);
  DECLARE cur1 CURSOR FOR SELECT type,value FROM testtable WHERE Type = 1;
  DECLARE cur1 CURSOR FOR SELECT type,value FROM testtable WHERE Type = 2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  if (SELECT COUNT(Value) FROM testtable WHERE Type = 1)
    = (SELECT COUNT(Value) FROM testtable WHERE Type = 2)
  then
      OPEN cur1;
      OPEN cur2;

      CREATE TEMPORARY TABLE test1 (
        Value1 varchar(12),
        Value2 varchar(12)
      )

      read_loop: LOOP
        FETCH cur1 INTO type1, value1;
        FETCH cur2 INTO type2, value2;

        IF done THEN
          LEAVE read_loop;
        END IF;
        INSERT INTO test1 VALUES(value1, value2);
      END LOOP;

      CLOSE cur1;
      CLOSE cur2;

      SELECT * FROM test1;
      DROP TABLE test1;
  ELSE
    SELECT t1.Value, t2.Value
      FROM testtable t1
        LEFT JOIN testtable t2 ON t2.Type = 2
      WHERE t1.Type = 1
    UNION SELECT t1.Value, t2.Value
      FROM testtable t1
        RIGHT JOIN testtable t2 ON t2.Type = 2
      WHERE t1.Type = 1;
  END IF;
END;

这很可怕,但它适用于您的三个示例。有些。

于 2013-03-09T14:45:23.637 回答