假设我有一个像这样的旋转排序数据集
ID 列 1 列 2 1个11 2 乙 22 3c 33 4 天 44 5 e 55
当我通过一次返回两条记录进行分页调用时,我会得到前两行。
假设我想返回相同的数据,但不旋转数据,所以我的数据集看起来像
ID 瓦尔上校 1 列 1 a 2 第 1 栏 b 3 第 1 栏 c 4 第 1 栏 d 5 列 1 e 1 第 2 栏 11 2 第 2 栏 22 3 第 2 栏 33 4 第 2 栏 44 5 第 2 栏 55
我想编写一个 sql 语句,该语句将返回与第一个示例中相同的数据,但不首先旋转数据。
一些额外的挑战
1)可能有 n 列,而不仅仅是两列
2) Tt 还应该支持所有列上的过滤器。这部分我已经解决了,见下文
过滤旋转数据 WHERE Col1 in ('a', 'b', 'c') AND Col2 in ('11', '22') 过滤未透视的数据 WHERE (Col = 'Col1' 和 Val in ('a', 'b', 'c')) 或 Col != 'Col1') AND (Col = 'Col2' 和 Val in ('11', '22')) 或 Col != 'Col2') 两个过滤器返回相同的结果。
过滤部分我已经弄清楚了,我卡在排序和分页上。
SQL 作为标准,不支持此类操作。 如果您希望它能够处理任意多的列以重新格式化数据,那么可以使用 Perl 的 DBI 接口之类的东西,它可以告诉您任何表的列名。 从那里您可以生成您的表创建。
要创建第二个表,插入将采用以下形式:
INSERT INTO newtable (id, col, val)
SELECT id, 'Col1', Col1 from oldtable
UNION
SELECT id, 'Col2', Col2 from oldtable;
只需为您想要包含的每一列创建一个额外的
UNION SELECT...
。
至于您的过滤查询,您使其变得不必要的复杂。 您的查询:
SELECT * FROM newtable
WHERE (Col = 'Col1' and Val in ('a', 'b', 'c')) or Col != 'Col1')
AND (Col = 'Col2' and Val in ('11', '22')) or Col != 'Col2')
可以重写为
SELECT * from newtable
WHERE ( Col = 'Col1' and Val in ('a','b','c') )
OR ( Col = 'Col2' and Val in ('11','22') )
每个单独的
OR
d 子句不会干扰其他子句。
我也不明白为什么人们试图在 SQL 中进行这样的嘲讽。 看来您正在尝试将合理的架构变成类似于键/值存储的东西。 这可能目前在孩子们中很流行,但你真的应该尝试学习如何通过良好的数据建模来使用 SQL 的全部功能。