Frage

Ich habe eine Tabelle von Daten, und ich Leute erlauben, Meta-Daten zu dieser Tabelle hinzugefügt werden.

Ich gebe ihnen eine Schnittstelle, die sie behandeln kann, als ob sie sind zusätzliche Spalten auf die Tabelle um ihre Daten gespeichert sind, aber ich bin tatsächlich die Daten in einer anderen Tabelle zu speichern.

Data Table
   DataID
   Data

Meta Table
   DataID
   MetaName
   MetaData

Also, wenn sie wollten eine Tabelle, die die Daten, das Datum gespeichert, und einen Namen, dann würde ich die Daten in der Datentabelle habe, und das Wort „Datum“ in metaName und das Datum in MetaData und eine anderen Zeile in der Meta-Tabelle mit "Namen" in metaName und den Namen in Metadaten.

Ich brauche jetzt eine Abfrage, die die Informationen aus diesen Tabellen und stellt sie als ob kommen aus einer einzigen Tabelle mit den beiden zusätzlichen Spalten „Data“ und „Name“ so an den Kunden nimmt würde es so aussehen es eine einzige Tabelle ist mit ihre benutzerdefinierten Spalten:

MyTable
   Data
   Date
   Name

Oder, mit anderen Worten, wie gehe ich von hier:

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

Um hier:

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

Vor Jahren, als ich dies in MySQL mit PHP tat, habe ich zwei Abfragen, die erste die zusätzlichen Meta-Daten zu erhalten, die zweite, sie alle miteinander zu verbinden. Ich hoffe, dass moderne Datenbanken haben alternative Methoden des Umgangs mit diesem.

Bezug zu Option 3 von href="https://stackoverflow.com/questions/218848/design-decision-dynamically-adding-data-question#218872">.

-Adam

War es hilfreich?

Lösung

Sie wollen jedes Ihrer Name-Wert-Paar Zeilen in der MyTable drehen ... Versuchen Sie, diese 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

Andere Tipps

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

Sie werden wahrscheinlich eine zusätzliche Klausel (AND Data = ‚some value‘) zurückkehren, um die Reihen der Benutzer interessiert ist.

hinzufügen möchten

AFAIK, können Sie dies auf der Server-Seite tun nur mit einer dynamischen SQL gespeicherten Prozedur.

Effektiv Sie den Code dynamisch generieren wollen, ist:

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'

Und hier ist Code, es zu tun:

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)

Sie könnten eine ähnliche Dynamik Technik mit dem CASE Anweisung Beispiel verwenden, um die Dreh auszuführen.

scroll top