Comment PIVOTer les données de la requête MSSQL et les récupérer en vue PHP
J'ai une base de données MSSQL 2005 avec un contenu de requête comme celui-ci:
nopas | code | Nom | ordre |
---|---|---|---|
00115301 | D031 | ADAM | 1 |
00130015 | D031 | ADAM | 2 |
00149998 | D026 | JAMES | 1 |
00149970 | D028 | FIKI | 1 |
00142641 | D028 | FIKI | 2 |
00127700 | D028 | FIKI | 3 |
Pour des raisons de rapport, j'ai besoin de produire un tableau comme:
ADAM | JAMES | FIKI | ... (nouvel enregistrement basé sur un contenu dynamique) |
---|---|---|---|
00115301 | 00149998 | 00149970 | ... |
00130015 | - | 00142641 | ... |
- | - | 00127700 | ... |
Quelqu'un peut-il m'aider??
Réponses
Vous pouvez faire un pivot avec des CASE
instructions. C'est fondamentalement la manière manuelle de pivoter et si vous utilisiez une version de SQL Server avant 2005, vous auriez besoin d'emprunter cette voie. SQL Server 2005 a ajouté la fonction PIVOT .
Parce que vous en avez besoin pour être dynamique, vous devrez utiliser du SQL dynamique . C'est beaucoup de travail pour les jambes, mais c'est certainement faisable.
Je vais créer le contenu de votre table dans une table temporaire globale (doit être globale pour fonctionner en SQL dynamique).
-- CREATE GLOBAL TEMPORARY TABLE
CREATE TABLE ##tablename (
[nopas] VARCHAR(8),
[code] VARCHAR(4),
[name] VARCHAR(64),
[order] SMALLINT
);
INSERT INTO ##tablename
([nopas], [code], [name], [order])
VALUES
('00115301','D031','ADAM', 1)
,('00130015','D031','ADAM', 2)
,('00149998','D026','JAMES', 1)
,('00149970','D028','FIKI', 1)
,('00142641','D028','FIKI', 2)
,('00127700','D028','FIKI', 3);
Ensuite, je vais SELECT
simplement placer les noms uniques dans une autre table temporaire et les associer à un IDENTITY
avec lequel je peux parcourir dans une boucle for.
SELECT IDENTITY(INT, 1,1) as [id], [name]
INTO #temp
FROM ##tablename
GROUP BY [name];
Vient maintenant la partie difficile. Le PRINT @dynSQL
génère ce que j'essaie de réaliser dynamiquement (ci-dessous). Nous devons SELECT
le [order]
, [name]
et [nopas]
pour le résultat final. Nous pivotons sur le [name]
dans la deuxième partie de l'énoncé et agrégons par MAX([nopas])
; mais comme nous contenons un [order]
regroupement dans le contenu de votre table d'origine, il ne récupérera que la MAX([nopas])
base de la MAX
valeur d'une seule ligne. Ainsi, le résultat est qu'il supprime l'agrégation. Si vous n'avez pas une [order]
colonne dans votre contenu original, nous aurions besoin d'utiliser la fonction ROW_NUMBER () * PARTITIONED BY
le [name]
pour produire que [order]
.
EDIT: J'ai découvert que la ROW_NUMBER()
fonction n'est disponible que dans SQL Server 2012 et plus récent.
-- PRINT @dynSQL result
SELECT * FROM
(SELECT [order], [name], [nopas]
FROM ##tablename) AS sourceTable
PIVOT(
MAX([nopas])
FOR [name] IN ([ADAM],[FIKI],[JAMES])
) AS pivotTable;
-- The leg work to create the dynamic SQL.
DECLARE @count INT = 1;
DECLARE @max INT = (SELECT MAX(id) FROM #temp);
DECLARE @dynSQL VARCHAR(2048) = 'SELECT * FROM
(SELECT [order], [name], [nopas]
FROM ##tablename) AS sourceTable
PIVOT(
MAX([nopas])
FOR [name] IN (';
SET @count = 1;
WHILE(@count <= @max)
BEGIN
SET @dynSQL += '[' + (SELECT [name] FROM #temp WHERE id = @count) + '],';
SET @count += 1;
END
SET @dynSQL = LEFT(@dynSQL, DATALENGTH(@dynSQL) -1) + ')
) AS pivotTable;';
PRINT @dynSQL;
EXEC (@dynSQL);
DROP TABLE ##tablename;
DROP TABLE #temp;
Oh, si vous voulez supprimer la [order]
colonne, du résultat. Vous pouvez utiliser SELECT * INTO ##newGlobalTable
dans le SQL dynamique, puis ALTER
la nouvelle table et DROP
la colonne.