对于MySQL,使用穷人的generate_series,这是通过视图完成的.MySQL是big four中唯一没有任何CTE功能的RDBMS.
实际上,您可以在支持视图的数据库上使用这种技术.这几乎就是所有的数据库
发电机技术来源:http://use-the-index-luke.com/blog/2011-07-30/mysql-row-generator#mysql_generator_code
我们所做的唯一微小的修改是,我们分别用乘法和加法替换了原始技术中的按位(shift left和bitwise or)技术;因为Sql Server和Oracle没有左移运算符.
这种抽象99%保证可以在除Oracle之外的所有数据库上工作;如果没有任何表,Oracle的SELECT
就无法运行,为了做到这一点,需要从虚拟表中进行 Select ,Oracle已经提供了一个表,称为DUAL
表.数据库可移植性是一个白日梦:-)
以下是适用于所有RDBMS的抽象视图,没有按位操作(在本场景中,这实际上不是必需的),并且在所有主要数据库中都有细微差别(我们在CREATE VIEW
中删除了OR REPLACE
个,只有Postgresql和MySQL支持它们).
甲骨文警告:在每个SELECT
表达式后面加FROM DUAL
CREATE VIEW generator_16
AS SELECT 0 n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL
SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL
SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL
SELECT 9 UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL
SELECT 12 UNION ALL SELECT 13 UNION ALL SELECT 14 UNION ALL
SELECT 15;
CREATE VIEW generator_256
AS SELECT ( ( hi.n * 16 ) + lo.n ) AS n
FROM generator_16 lo, generator_16 hi;
CREATE VIEW generator_4k
AS SELECT ( ( hi.n * 256 ) + lo.n ) AS n
FROM generator_256 lo, generator_16 hi;
CREATE VIEW generator_64k
AS SELECT ( ( hi.n * 256 ) + lo.n ) AS n
FROM generator_256 lo, generator_256 hi;
CREATE VIEW generator_1m
AS SELECT ( ( hi.n * 65536 ) + lo.n ) AS n
FROM generator_64k lo, generator_16 hi;
然后使用以下查询:
SELECT t.value, t.cnt, i.n
FROM tbl t
JOIN generator_64k i
ON i.n between 1 and t.cnt
order by t.value, i.n
Postgresql:http://www.sqlfiddle.com/#!1/1541d/1
甲骨文:http://www.sqlfiddle.com/#!4/26c05/1
Sql Server:http://www.sqlfiddle.com/#!6/84bee/1
MySQL:http://www.sqlfiddle.com/#!2/78f5b/1