0

我正在使用 SQL Server 2008 R2。我有一个表结构如下:

Id (Identity): int  
GroupId:       int  
Field Id:      int  
Field Name:    nvarchar(1000)  
Value:         nvarchar(max)  

这张表可以看作是一个键值对结构。

因此,如果我在 UI 中有以下记录:

Due Date    | Target Date       | Status  
-----------------------------------
5-Jun-2013  |       4-June-2013 | Pending  
10-Jun-2013 |       8-June-2013 | Completed  
15-Jun-2013 |      11-June-2013 | Pending  

在数据库中,每一列都作为单独的记录。所以数据库将有:

Id  | Group Id  | Field Id  | Field Name    | Value  
-----------------------------------------------------------
1   | 1         | 1         | Due Date      | 5-Jun-2013  
2   | 1         | 2         | Target Date   | 4-Jun-2013  
3   | 1         | 3         | Status        | Pending  

4   | 2         | 1         | Due Date      | 10-Jun-2013  
5   | 2         | 2         | Target Date   | 8-Jun-2013  
6   | 2         | 3         | Status        | Completed  

7   | 3         | 1         | Due Date      | 15-Jun-2013  
8   | 3         | 2         | Target Date   | 11-Jun-2013  
9   | 3         | 3         | Status        | Pending  

从数据库中检索时,我希望以与 UI 中看到的格式相同的格式获得输出。考虑到该表将包含大量数据,获得此结果的最佳方法是什么?

在这方面的任何帮助都将非常有用。

4

2 回答 2

1

无论这是否是一个好的设计,您都可以使用 OP 中提供的数据完成您想要的操作。关键是要注意 id 之间的差异标识了行。我必须强调,设计中应该包含明确的“记录”引用,因此我将这条消息称为 hack。

select (id - FieldId),
       max(case when FieldName = 'DueDate' then value end) as DueDate,
       max(case when FieldName = 'TargetDate' then value end) as TargetDate,
       max(case when FieldName = 'Status' then value end) as Status
from t
group by (id - FieldId)

顺便说一句,您必须将日期存储为字符串这一事实进一步表明数据结构存在问题。即使在 EAV 结构中,您也可以将“ValueStr”、“ValueDate”、“ValueInt”作为单独的列来存储不同的值(或使用 sqlvariant 类型)。

于 2013-06-14T09:28:03.043 回答
0

试试这个

SELECT 
      MAX(CASE WHEN fieldName = 'Due Date' THEN fvalue ELSE NULL END) [Due Date],
      MAX(CASE WHEN fieldName = 'Target Date' THEN fvalue ELSE NULL END) [Target Date],
      MAX(CASE WHEN fieldName = 'Status' THEN fvalue ELSE NULL END) [Status] 
FROM #tmp GROUP BY (id - FieldId)
于 2013-06-14T10:18:02.310 回答