Welche SQL-Abfrage oder Ansicht wird „dynamische Spalten“
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
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.