Dans ma base de données SQL 2005, j'ai une table avec des valeurs stockées en tant qu'ID avec des relations avec d'autres tables. Donc dans mon MyDBO.warranty tableau, je stocke product_id au lieu de product_name afin d'économiser de l'espace. Le nom_produit est stocké dans MyDBO.products.SQL: imbriqué SELECT avec plusieurs valeurs dans un seul champ
Lorsque le service marketing tire les informations démographiques, la requête sélectionne le nom correspondant pour chaque ID de tableaux connexes (dégrossi par souci de concision):
SELECT w1.warranty_id AS "No.",
w1.created AS "Register Date"
w1.full_name AS "Name",
w1.purchase_date AS "Purchased",
(
SELECT p1.product_name
FROM WarrDBO.products p1 WITH(NOLOCK)
WHERE p1.product_id = i1.product_id
) AS "Product Purchased",
i1.accessories
FROM WarrDBO.warranty w1
LEFT OUTER JOIN WarrDBO.warranty_info i1
ON i1.warranty_id = w1.warranty_id
ORDER BY w1.warranty_id ASC
Maintenant, mon problème est que la colonne « accessoires » sur les magasins de table de warranty_info plusieurs valeurs:
No. Register Date Name Purchased Accessories
---------------------------------------------------------------------
1500 1/1/2008 Smith, John Some Product 5,7,9
1501 1/1/2008 Hancock, John Another 2,3
1502 1/1/2008 Brown, James And Another 2,9
que je dois faire quelque chose de similaire avec « Accessoires » que je l'ai fait avec « produit » et tirer accessory_name du MyDBO.accessories table utilisant accessory_id. Je ne suis pas sûr de savoir par où commencer, car je devrais d'abord extraire les ID, puis concaténer plusieurs valeurs dans une chaîne. Donc, chaque ligne aurait "accessname1, accessoryname2, accessoryname3":
No. Register Date Name Purchased Accessories
---------------------------------------------------------------------
1500 1/1/2008 Smith, John Some Product Case,Bag,Padding
1501 1/1/2008 Hancock, John Another Wrap,Label
1502 1/1/2008 Brown, James And Another Wrap,Padding
Comment faire?
EDIT >> Affichage mon code final:
J'ai créé cette fonction:
CREATE FUNCTION SQL_GTOInc.Split
(
@delimited varchar(50),
@delimiter varchar(1)
) RETURNS @t TABLE
(
-- Id column can be commented out, not required for sql splitting string
id INT identity(1,1), -- I use this column for numbering splitted parts
val INT
)
AS
BEGIN
declare @xml xml
set @xml = N'<root><r>' + replace(@delimited,@delimiter,'</r><r>') + '</r></root>'
insert into @t(val)
select
r.value('.','varchar(5)') as item
from @xml.nodes('//root/r') as records(r)
RETURN
END
et mis à jour mon code en conséquence:
SELECT w1.warranty_id,
i1.accessories,
(
CASE
WHEN i1.accessories <> '' AND i1.accessories <> 'NULL' AND LEN(i1.accessories) > 0 THEN
STUFF(
(
SELECT ', ' + a1.accessory
FROM MyDBO.accessories a1
INNER JOIN MyDBO.Split(i1.accessories, ',') a2
ON a1.accessory_id = a2.val
FOR XML PATH('')
), 1, 1, ''
)
ELSE ''
END
) AS "Accessories"
FROM MyDBO.warranty w1
LEFT OUTER JOIN MyDBO.warranty_info i1
ON i1.warranty_id = w1.warranty_id
Eh bien, il (devrait) aller sans dire, mais vous ne devriez pas stocker une colonne de acccessories dans les warranty_info comme ça. Vous devriez avoir une table de jointure, Warranty_info_accessories qui contient deux colonnes: le warranty_id et le accessory_id. Cela simplifierait grandement votre problème. – Gerrat
Je suis d'accord, c'est ce que j'aurais fait si j'avais construit la structure. Malheureusement, l'auteur de la DB faisait tout ce qu'il pouvait pour économiser de l'espace, et c'était l'une des méthodes qu'il utilisait. – Dexter
J'apprécie toute l'aide des gars, et si je pouvais choisir plus d'une réponse, je le ferais. Apparemment, je ne lisais pas assez attentivement et j'ai omis le 'FOR XML PATH ('')' dans ma déclaration, causant l'erreur. J'ai appliqué toutes les suggestions, et cela ne fonctionne pas parfaitement. – Dexter