2010-07-14 44 views
1

我有两个表。在一个表我的宿舍有最多可容纳像这样的列表:为现有表中的每一行创建临时行

dorm_building | dorm_room | max_occupancy 

然后,我有个同学的名单,他们被分配到喜欢这个房间:

people_id | people_name | dorm_building | dorm_room 

我想为每个潜在的居住者创建一张表格(例如,如果一个房间有五个可能的居住者,则该表应该有五行)。然后我想将这些学生记录加入到这张表中。然后,我将使用Reporting Services将其吐出,以提供关于谁在哪个房间以及哪些空白点仍然可用的视觉映射。

帮助?

回答

5
With Numbers As 
    (
    Select Row_Number() Over (Order By C1.object_id) As Value 
    From sys.syscolumns As C1 
     Cross Join sys.syscolumns As C2 
    ) 
    , NumberedStudents As 
    (
    Select people_id, people_name, dorm_building, dorm_room 
     , Row_Number() Over (Partition By dorm_building, dorm_room Order By people_id) As OccupantNum 
    From Students 
    ) 
Select ... 
From DormRooms 
    Join Numbers 
     On N.Value <= DormRooms.max_occupancy 
    Left Join NumberedStudents 
     On NumberedStudents.dorm_building = DormRooms.dorm_building 
      And NumberedStudents.dorm_room = DormRooms.dorm_room 
      And NumberedStudents.OccupantNum= Numbers 

我在此解决方案中使用了SQL Server 2005及更高版本中提供的两个功能。第一种是公用表表达式或CTE,第二种是排名函数(在这种情况下是Row_Number)。通用表表达式是Numbers表和NumberedStudents表。将这些视为保存的视图或查询。CTE通过交叉连接任意两个表(我选择了sys.syscolumns)来创建数字的顺序列表。这使我能够生成您请求的“占位符”行。 Row_Number函数只是为返回的每一行创建一个顺序数字列表。

在NumberedStudents CTE中,我还使用了Row_Number函数的Partition By功能,该功能重新启动每个dorm_building和dorm_room的占用者编号。这将有效地给房间里的每个学生一个连续的编号。

+0

谢谢。这应该工作。我想知道是否可以这样做(伪): 对于(select * from dorms)中的每一行 i = 0 if i <= row.maximum_occupants then insert into #temp row.dorm_name,i end if Next – davemackey 2010-07-14 20:19:15

+0

@davemackey - 一般来说,如果您绝对必须这样做,并且只有在没有基于集合的解决方案时才会发生,您只需要在SQL中采用迭代解决方案。在这种情况下,我认为你确实有一套基于解决方案的解决方案,所以我会首先解决这个问题。 – Thomas 2010-07-15 04:12:04

2

你其实需要的临时表吗?为什么不只是写一个相当简单的查询,像:

select dr.dorm_building, dr.dorm_room, dr.max_occupancy, ra.people_id, ra.people_name 
from dorm_room_table dr left join room_assignment_table ra 
on dr.dorm_building = ra.dorm_building and dr.dorm_room = ra.dorm_room 

然后使用一个表,通过dorm_room和dorm_building分组,从细节行报告占用和一组基础报告空置的地方(场max_occupancy!值 - CountRows())。