我有一个SQL查询,结果如下:

value | count
------+------
foo   |     1
bar   |     3
baz   |     2

现在我想把它展开,这样每一个大于1的行都会出现多次.我还需要对这些行进行编号.所以我会得到:

value | count | index
------+-------+------
foo   |     1 |     1
bar   |     3 |     1
bar   |     3 |     2
bar   |     3 |     3
baz   |     2 |     1
baz   |     2 |     2

我必须在所有主要数据库(Oracle、SQL Server、MySQL、PostgreSQL,也许还有更多)上实现这一点.因此,一个能够跨不同数据库工作的解决方案是理想的,但让它在任何数据库上工作的聪明方法是值得赞赏的.

推荐答案

对于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 leftbitwise 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

Postgresql相关问答推荐

从子查询中的排序结果中获取前X行

为什么Postgres在打印时能完全缩短时间跨度?

列不明确

PostgreSQL:动态SELECT查询

Select 与输入数组完全相交的所有行?

PostgreSQL TIMESTAMPTZ 不适用于 SpringBoot Java Query

Windows上的psql:错误:编码UTF8的字节序列无效:0xc8 0x20

在 Ubuntu 11.04 服务器中启用对 postgresql 的 PHP 支持

在 to_tsquery 中转义特殊字符

如何让 Flask SQLAlchemy 重用数据库连接?

如何将 postgres 数据库转换为 sqlite

datagrip 无法应用更改 此表是只读的

是否可以在 PostgreSQL 中部分刷新materialized视图?

从 PostgreSQL 中的时间戳获取日期

如何在数据库表中查找重复条目?

设置 Phoenix 框架和 Ecto 以使用 UUID:如何插入生成的值?

无法在 postgresql hibernate 中使用名为user的表

使用枚举与布尔值?

带有 WITH 子句的查询时出现 Postgresmissing FROM-clause entry错误

如何在不丢失openproject数据的情况下将postgresql数据库从10升级到12