J'ai besoin de prendre les résultats d'une requête par élément de ligne et de créer une liste délimitée par des points-virgules des matériaux qui composent cet élément.SQL Server 2008 - Chaîne de concaténation
Schéma Maquillage:
Tables: LineItems (article unique Listing) LineItems_Materials (Many to Many) Matériaux (matériel unique Annonce)
Articles de ligne: ID | LineItem 1 | '1A .1'
LineItems_Materials: ID | LineItemID | MaterialID 1 | 1 | 1 2 | 1 | 2 3 | 1 | 3
Matériaux: ID | Matériel 1 | béton 2 | Acier 3 | Dirt
Donc, pour la ligne 1 article (1A.1) Je veux montrer béton, acier, Dirt
Je sais que je peux écrire une fonction pour le faire. J'ai utilisé CTE dans la fonction .... Je pourrais aussi utiliser une boucle while. Y a-t-il une autre méthode qui serait meilleure?
Voici ce que je (script construire des objets, des données de charge et fonction de création):
SCRIPT:
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[test].[UFN_LineItem_Materials]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
DROP FUNCTION [test].[UFN_LineItem_Materials]
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[test].[LineItems]') AND type in (N'U'))
DROP TABLE [test].[LineItems]
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[test].[Materials]') AND type in (N'U'))
DROP TABLE [test].[Materials]
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[test].[LineItems_Materials]') AND type in (N'U'))
DROP TABLE [test].[LineItems_Materials]
GO
IF EXISTS (SELECT * FROM sys.schemas WHERE name = N'test')
DROP SCHEMA [test]
GO
CREATE SCHEMA [test] AUTHORIZATION [dbo]
GO
Create Table test.Materials(
MaterialID INT IDENTITY(1,1),
Material varchar(100));
Insert Into test.Materials
Values('Concrete');
Insert Into test.Materials
Values('Steel');
Insert Into test.Materials
Values('Dirt');
GO
Create Table test.LineItems_Materials(
LineItemMaterialID INT IDENTITY(1,1),
LineItemID INT,
MaterialID INT)
GO
Insert Into test.LineItems_Materials
Select 1,1
UNION
Select 1,2
UNION
Select 1,3
GO
CREATE TABLE [test].[LineItems](
[LineItemID] [int] IDENTITY(1,1) NOT NULL,
[ItemNumber] [varchar](25) NULL
) ON [PRIMARY]
GO
Insert Into [test].[LineItems]
Select '1A.1'
GO
-------------------------------------------------------------
--Build Material Strings (;) example: List of Materials
------------------------------------------------------------
CREATE FUNCTION test.UFN_LineItem_Materials(@LineItemID INT)
RETURNS VARCHAR(100)
AS
BEGIN
DECLARE @Materials Varchar(100) = ''
;with CTE
AS(
Select lm.LineItemID,m.MaterialID,m.Material
from test.LineItems_Materials lm
inner join test.Materials m on lm.MaterialID = m.MaterialID
Where lm.LineItemID = @LineItemID
)
Select @Materials += ';' + c.Material
from CTE c;
SET @Materials = substring(@Materials,2,LEN(@Materials)-1);
RETURN @Materials;
END
GO
Select lm.LineItemID,test.UFN_LineItem_Materials(lm.LineItemID) Materials
From test.Materials m
inner join test.LineItems_Materials lm on m.MaterialID = lm.MaterialID
Where m.Material = 'Concrete'
D'autres idées?
apprécient toujours les évaluations
-S-
qui est de l'argent ... merci! – scarpacci
C'est vraiment proche de ce que j'ai construit – scarpacci
+1 pour la présentation la plus simple de 'for xml' – DonBecker