替代具有聚合连接功能

时间:2009-08-14 20:37:59

标签: sql sql-server

我在SQL Server 2005中有以下表格

ReceiptPoint: ID (PK), Name  
GasIndexLocation: Location (PK)  
ReceiptPointIndexLocation: ReceiptPointId (FK), IndexLocation (FK), StartDate, EndDate  

在任何一天,ReceiptPoint都可以映射到一个或多个IndexLocations。我需要能够在某一天看到与IndexLocations进行比较的内容。对于具有多个IndexLocations的ReceiptPoint,它应显示为某种分隔列表(用于向用户显示)。

我有两个问题。
1)ReceiptPointIndexLocation目前没有主键。处理此问题的最佳方法是在表上添加递增索引字段吗?

2)如何获取给定日期使用的IndexLocations列表?据我所知,它需要使用不存在的字符串连接聚合函数。

我应该采用完全不同的方式来组织数据吗?这仍处于开发阶段,所以我愿意改变它。

3 个答案:

答案 0 :(得分:1)

1)ReceiptPointIndexLocation的主键应该是全部四列。但是,这不会停止具有相同位置和收据的重叠日期的条目。当您可以使用复合键识别行时,不需要标识列。

2)SQL:

 SELECT (SELECT t.indexlocation + ','
   FROM RECEIPTPOINTINDEXLOCATION t
  WHERE t.startdate >= @start
    AND t.enddate <= @end
FOR XML PATH(''))

答案 1 :(得分:1)

有几种方法可以在SQL中聚合字符串。您应该阅读这篇文章Concatenating Row Values in Transact-SQL。最有效的方法是使用FOR XML PATH(',')技巧。

答案 2 :(得分:0)

我建议在表中添加一个递增索引以用作主键。如果您不这样做,我认为SQL Server会在幕后自动执行此操作,但我强烈建议您明确定义该列。这样,您可以通过主键引用各个行,而不必搜索两个交叉引用值。

另外,观察交叉引用表上的聚类。如果添加索引主键,请不要在索引主键上进行群集。您可能希望在两个外键上进行聚类,但您可以选择更有意义的外键。例如:

ALTER TABLE ReceiptPointIndexLocation 
    ADD CONSTRAINT UK_ReceiptPointIndexLocation_ReceiptPointId_IndexLocation
        UNIQUE CLUSTERED (ReceiptPointId, IndexLocation)

或者,如果(ReceiptPointId,IndexLocation)的组合足够独特,您可以将其作为主键。