我正在使用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中看到的格式相同的格式输出。获得此结果的最佳方法是什么,考虑到表格会有大量数据?
这方面的任何帮助都非常有用。
答案 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)