我有一个数据表,我允许人们将元数据添加到该表中。
我给他们一个接口,允许他们对待它,好像他们在表中存储数据的额外列,但我实际上是将数据存储在另一个表中。
Data Table
DataID
Data
Meta Table
DataID
MetaName
MetaData
因此,如果他们想要一个存储数据,日期和名称的表,那么我将拥有数据表中的数据,以及metaname中的“Date”一词,以及MetaData中的日期,以及另一个在meta表中使用“名称”的元数据行中的行和元数据中的名称。
我现在需要一个查询来获取这些表中的信息,并将其呈现为来自单个表,其中包含两个附加列“数据”和“名称”,因此对于客户来说,它看起来就像是一个表他们的自定义列:
MyTable
Data
Date
Name
或者,换句话说,我该如何离开这里:
Data Table
DataID Data
1 Testing!
2 Hello, World!
Meta Table
DataID MetaName MetaData
1 Date 20081020
1 Name adavis
2 Date 20081019
2 Name mdavis
到这里:
MyTable
Data Date Name
Testing! 20081020 adavis
Hello, World! 20081019 mdavis
多年前,当我使用PHP在MySQL中执行此操作时,我做了两个查询,第一个获取额外的元数据,第二个将它们连接在一起。我希望现代数据库有替代方法来解决这个问题。
与this question的选项3相关。
- 亚当
答案 0 :(得分:2)
您想要在MyTable中调整每个名称 - 值对行...试试这个sql:
DECLARE @Data TABLE (
DataID INT IDENTITY(1,1) PRIMARY KEY,
Data VARCHAR(MAX)
)
DECLARE @Meta TABLE (
DataID INT ,
MetaName VARCHAR(MAX),
MetaData VARCHAR(MAX)
)
INSERT INTO @Data
SELECT 'Data'
INSERT INTO @Meta
SELECT 1, 'Date', CAST(GetDate() as VARCHAR(20))
UNION
SELECT 1, 'Name', 'Joe Test'
SELECT * FROM @Data
SELECT * FROM @Meta
SELECT
D.DataID,
D.Data,
MAX(CASE MetaName WHEN 'Date' THEN MetaData ELSE NULL END) as Date,
MAX(CASE MetaName WHEN 'Name' THEN MetaData ELSE NULL END) as Name
FROM
@Meta M
JOIN @Data D ON M.DataID = D.DataID
GROUP BY
D.DataID,
D.Data
答案 1 :(得分:1)
SELECT DataTable.Data AS Data, MetaTable.MetaData AS Date, MetaTable.MetaName AS Name
FROM DataTable, MetaTable
WHERE DataTable.DataID = MetaTable.DataID
您可能希望添加一个附加子句(AND Data ='some value')来返回用户感兴趣的行。
答案 2 :(得分:0)
AFAIK,只能使用动态SQL
存储过程在服务器端执行此操作。
有效地,您想要动态生成的代码是:
SELECT [Data Table].*
,[MyTable Date].MetaData
,[MyTable Name].MetaData
FROM [Data Table]
LEFT JOIN [MyTable] AS [MyTable Date]
ON [MyTable Date].DataID = [Data Table].DataID
AND [MyTable Date].MetaName = 'Date'
LEFT JOIN [MyTable] AS [MyTable Name]
ON [MyTable Name].DataID = [Data Table].DataID
AND [MyTable Name].MetaName = 'Name'
这是代码:
DECLARE @sql AS varchar(max)
DECLARE @select_list AS varchar(max)
DECLARE @join_list AS varchar(max)
DECLARE @CRLF AS varchar(2)
DECLARE @Tab AS varchar(1)
SET @CRLF = CHAR(13) + CHAR(10)
SET @Tab = CHAR(9)
SELECT @select_list = COALESCE(@select_list, '')
+ @Tab + ',[MyTable_' + PIVOT_CODE + '].[MetaData]' + @CRLF
,@join_list = COALESCE(@join_list, '')
+ 'LEFT JOIN [MyTable] AS [MyTable_' + PIVOT_CODE + ']' + @CRLF
+ @Tab + 'ON [MyTable_' + PIVOT_CODE + '].DataID = [DataTable].DataID' + @CRLF
+ @Tab + 'AND [MyTable_' + PIVOT_CODE + '].MetaName = ''' + PIVOT_CODE + '''' + @CRLF
FROM (
SELECT DISTINCT MetaName AS PIVOT_CODE
FROM [MyTable]
) AS PIVOT_CODES
SET @sql = 'SELECT [DataTable].*' + @CRLF
+ @select_list
+ 'FROM [DataTable]' + @CRLF
+ @join_list
PRINT @sql
--EXEC (@sql)
您可以使用CASE
语句示例使用类似的动态技术来执行数据透视。