什么 SQL 查询或视图将显示“动态列”?

发布于 2024-07-06 19:57:38 字数 1223 浏览 8 评论 0原文

我有一个数据表,我允许人们向该表添加元数据。

我为他们提供了一个界面,允许他们将其视为向存储数据的表添加额外的列,但实际上我将数据存储在另一个表中。

Data Table
   DataID
   Data

Meta Table
   DataID
   MetaName
   MetaData

因此,如果他们想要一个存储数据、日期和名称的表,那么我将在数据表中包含数据,在元名称中包含“日期”一词,在元数据中包含日期,以及数据表中的另一行元表,元名称中包含“名称”,元数据中包含名称。

我现在需要一个查询,从这些表中获取信息,并将其呈现为来自带有两个附加列“数据”和“名称”的单个表,因此对于客户来说,看起来就像有一个带有自定义列的表:

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 中执行此操作时,我做了两个查询,第一个查询获取额外的元数据,第二个查询将它们连接在一起。 我希望现代数据库有处理这个问题的替代方法。

此问题的选项 3 相关。

-亚当

I have a table of data, and I allow people to add meta data to that table.

I give them an interface that allows them to treat it as though they're adding extra columns to the table their data is stored in, but I'm actually storing the data in another table.

Data Table
   DataID
   Data

Meta Table
   DataID
   MetaName
   MetaData

So if they wanted a table that stored the data, the date, and a name, then I'd have the data in the data table, and the word "Date" in metaname, and the date in MetaData, and another row in the meta table with "Name" in metaname and the name in metadata.

I now need a query that takes the information from these tables and presents it as though coming from a single table with the two additional columns "Data" and "Name" so to the customer it would look like there's a single table with their custom columns:

MyTable
   Data
   Date
   Name

Or, in other words, how do I go from here:

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

To here:

MyTable
   Data          Date             Name
   Testing!      20081020         adavis
   Hello, World! 20081019         mdavis

Years ago when I did this in MySQL using PHP, I did two queries, the first to get the extra meta data, the second to join them all together. I'm hoping that modern databases have alternate methods of dealing with this.

Related to option 3 of this question.

-Adam

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

━╋う一瞬間旳綻放 2024-07-13 19:57:38

您想要旋转 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

You want to pivot each of your name-value pair rows in the MyTable... Try this 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
醉生梦死 2024-07-13 19:57:38
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')来返回用户感兴趣的行。

SELECT DataTable.Data AS Data, MetaTable.MetaData AS Date, MetaTable.MetaName AS Name
FROM DataTable, MetaTable
WHERE DataTable.DataID = MetaTable.DataID

You'll probably want to add an additional clause (AND Data = 'some value') to return the rows the user is interested in.

青柠芒果 2024-07-13 19:57:38

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 语句示例来执行数据透视。

AFAIK, you can do this on the server-side only with a dynamic SQL stored procedure.

Effectively the code you want to generate dynamically is:

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'

And here's code to do it:

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)

You could use a similar dynamic technique using the CASE statement example to perform the pivot.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文