我有一张桌子:
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语句执行此操作的最优雅方法是什么?
答案 0 :(得分: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;
这是fiddle。
答案 1 :(得分: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
输出:
One | Second
--------------------
1val1 | 2val1
1val1 | 2val2
1val1 | 2val3
1val2 | 2val1
1val2 | 2val2
1val2 | 2val3
答案 2 :(得分: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;
这很可怕,但它适用于你的三个例子。一些。