根据数据跳过查询中的行

时间:2010-10-22 01:23:45

标签: .net sql sql-server sql-server-2005 sql-server-2008

我的数据如下

DECLARE @tmp TABLE(cid int, colspan int, rowspan int, corder int)
INSERT INTO @tmp
SELECT 1,2,null,1
UNION
SELECT 2,null,null,2
UNION
SELECT 3,null,null,3
UNION
SELECT 4,3,null,4
UNION
SELECT 5,null,null,5
UNION
SELECT 6,null,null,6
UNION
SELECT 7,null,null,7

我想查询返回

cid   colspan  rowspan  corder
-------------------------------------
1      2       null      1
3      null    null      3
4      3       null      4
7      null    null      7

记录将由corder订购,然后使用colspan值跳过下一条记录(如果colspan = 2则跳过下一条1,如果3则跳过下一条2)。这可以使用查询吗?

为什么我想要这些数据 - 我正在尝试将此数据绑定到转发器控件(表模板)以创建动态表,并且当存在colspan> 0我不希望我的转发器生成td项目,以便它能正确跨越。

3 个答案:

答案 0 :(得分:3)

因为(正如@Sam Saffron在评论中所说的那样)在过程代码中执行此类操作确实要容易得多,这意味着您的表没有为SQL设计正确。

在SQL数据库中,每行应描述单个实体(或实体之间的单个关系)。如果一个足够普通的设计缺陷,就不这样做。例如,请考虑此薪资表:

CREATE TABLE Payroll
(
 employee_number CHAR(10) NOT NULL
    REFERENCES Personnel (employee_number), 
 effective_date DATE NOT NULL, 
 salary_amount DECIMAL(19, 4) NOT NULL
    CHECK (salary_amount >= 0), 
 UNIQUE (effective_date, employee_number)
);

INSERT INTO Payroll (employee_number, effective_date, salary_amount)
   VALUES ('U83GHVPSGP', '2001-01-01', 5000), 
          ('U83GHVPSGP', '2002-01-01', 7000), 
          ('U83GHVPSGP', '2002-01-01', 9000);

这里的问题是它是建模周期,但是每个周期的结束日期是从另一行的开始日期开始的,即实体(作为单个工资期)使用两行建模,每个开始日期在两个角色中扮演两个角色。数据库。副作用是一个简单的查询,例如“让我这个期间员工U83GHVPSGP支付5000 MNT”是非常重要的(从实现的角度来看,它将涉及一个相关的子查询,它很可能在给定的情况下表现不佳SQL平台)。上表将遭受非明显的异常,例如:删除U83GHVPSGP收到7000 MNT的行将隐式更改另一行的数据,即现在看起来U83GHVPSGP支付5000 MNT,直到'2002-01-01'才真正如此。

你有一个名为rowspan的列的事实是我见过的关于这种设计缺陷的“气味”的最完美的例子。

我并不是说听起来很刺耳。毫无疑问,您的表对过程代码非常有意义,因此使用过程代码而不是SQL。

SQL最适合基于集合的解决方案,因此如果您想使用SQL,那么请考虑重新设计表,以便在实体之间的关系中对单独表中的实体进行建模,并确保表的两种风格不会拆分单个实体/关系的数据跨越多行。

答案 1 :(得分:1)

尝试使用递归CTE,如下所示:

with cte as (
select t.* from @tmp t where corder = 1
union all 
select t.* from @tmp t join cte c on t.corder = (c.corder + coalesce(c.colspan,1))
)
select * from cte

答案 2 :(得分:0)

您可以使用返回实际表的CLR表值函数。 CLR函数是您可以用您的母语C#,VB等编写的函数,并且dll嵌入在数据库中。

从这里了解更多信息:

http://msdn.microsoft.com/en-us/library/ms131103.aspx