Question

J'ai une table de données et j'autorise les gens à ajouter des métadonnées à cette table.

Je leur donne une interface qui leur permet de le traiter comme s'ils ajoutaient des colonnes supplémentaires à la table dans laquelle leurs données sont stockées, mais je stocke en fait les données dans une autre table.

Data Table
   DataID
   Data

Meta Table
   DataID
   MetaName
   MetaData

Donc, s'ils voulaient une table qui stocke les données, la date et un nom, les données figureraient dans la table de données et le mot "Date". dans le métaname et la date dans MetaData, ainsi qu'une autre ligne de la table meta avec l'option "Nom". dans le métaname et le nom dans les métadonnées.

J'ai maintenant besoin d'une requête qui extrait les informations de ces tables et les présente comme si elles provenaient d'une seule table avec les deux colonnes supplémentaires " Données " et " Nom " pour le client, il semblerait qu'il y ait une seule table avec leurs colonnes personnalisées:

MyTable
   Data
   Date
   Name

Ou, en d'autres termes, comment puis-je partir d'ici:

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

Jusqu'ici:

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

Il y a des années, lorsque je travaillais dans PHP avec MySQL, j'ai effectué deux requêtes, la première pour obtenir les métadonnées supplémentaires et la seconde pour les réunir. J'espère que les bases de données modernes disposent de méthodes alternatives pour gérer ce problème.

Lié à l'option 3 de la question .

-Adam

Était-ce utile?

La solution

Vous souhaitez faire pivoter chacune des lignes de votre paire nom-valeur dans la table MyTable ... Essayez ceci 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

Autres conseils

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

Vous voudrez probablement ajouter une clause supplémentaire (AND Data = 'une valeur') pour renvoyer les lignes qui intéressent l'utilisateur.

Si vous le voulez bien, vous ne pouvez le faire côté serveur qu'avec une procédure stockée dynamique SQL .

Le code que vous souhaitez générer de manière dynamique est le suivant:

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'

Et voici le code pour le faire:

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)

Vous pouvez utiliser une technique dynamique similaire en utilisant l'exemple d'instruction CASE pour effectuer le pivot.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top