查询键值对结构

时间:2013-06-14 08:49:11

标签: sql sql-server

我正在使用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中看到的格式相同的格式输出。获得此结果的最佳方法是什么,考虑到表格会有大量数据?

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

2 个答案:

答案 0 :(得分: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类型)。

答案 1 :(得分: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)