SQL排序/分页问题

时间:2011-08-06 04:14:19

标签: sql sorting paging pivot

假设我有一个像这样的透视排序数据集

ID    Col1    Col2
1     a       11
2     b       22
3     c       33
4     d       44
5     e       55

当我通过一次返回两条记录进行分页调用时,我会得到前两行。

假设我想返回相同的数据但不转动数据,因此我的数据集看起来像

ID    Col     Val
1     Col1    a 
2     Col1    b
3     Col1    c
4     Col1    d
5     Col1    e
1     Col2    11
2     Col2    22 
3     Col2    33
4     Col2    44 
5     Col2    55

我想编写一个sql语句,该语句将返回与第一个示例中相同的数据但不首先转动数据。

一些额外的挑战

1)可能有n列不仅仅是两个

2)Tt还应支持所有列的过滤器。这部分我已经解决了,见下文

Filter on pivoted data
WHERE Col1 in ('a', 'b', 'c')
AND Col2 in ('11', '22')

Filter on unpivoted data
WHERE (Col = 'Col1' and Val in ('a', 'b', 'c')) or Col != 'Col1') 
AND (Col = 'Col2' and Val in ('11', '22')) or Col != 'Col2') 

Both filters return the same results.

我已经想到的过滤器部分已经停留在排序和分页上了。

1 个答案:

答案 0 :(得分:1)

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中运行这样的travesties。您似乎正在尝试将合理的架构设置为类似于键/值存储的东西。现在,这对孩子们来说可能风靡一时,但你应该真正学会如何利用SQL的全部功能和良好的数据建模。