簡體   English   中英

SQL Server 2008-串聯字符串

[英]SQL Server 2008 - Concatenate String

我需要獲取每個訂單項的查詢結果,並建立用分號分隔的組成該項目的材料的列表。

模式組成:

表格:LineItems(唯一物料清單)LineItems_Materials(多對多)物料(Unique物料清單)

訂單項:ID | LineItem 1 |'1A.1'

LineItems_Materials:ID | LineItemID | MaterialID 1 | 1 | 1 2 | 1 | 2 3 | 1 | 3

材料:ID |材料1 |混凝土2 |鋼3 |土

因此,對於訂單項1(1A.1),我希望它顯示混凝土,鋼,土

我知道我可以編寫一個函數來做到這一點。 我在函數中使用了CTE ....我也可以使用while循環。 還有另一種更好的方法嗎?

這是我所擁有的(腳本將生成對象,加載數據和創建函數):

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'

還有其他想法嗎?

總是感謝反饋

--S

如果要跨行連接值,請使用FOR XML技巧,例如:

SELECT Name + ',' 
FROM Project
FOR XML PATH('') 

這是一個更完整的示例:

select LineItemID, (
        Select m.Material + ','
        From test.Materials m 
        inner join test.LineItems_Materials lm1 on m.MaterialID = lm1.MaterialID 
        Where m.MaterialID in (select MaterialID from test.LineItems_Materials where LineItemID = lm2.LineItemID)
        FOR XML PATH('')  
    ) as Materials
from test.LineItems_Materials lm2
group by LineItemID

嘗試這樣的事情:

declare @x table (x varchar(5))
insert @x values ('AAAA')
insert @x values ('BBBB')
insert @x values ('CCCC')

SELECT
    STUFF(
             (
                SELECT ','+x
                    FROM @x
                   FOR XML PATH('') 

             ), 1, 1, ''
         ) AS ColName

輸出:

ColName
-------------------
AAAA,BBBB,CCCC

(1 row(s) affected)

或像這樣:

declare @x table (RowID int, x varchar(5))
insert @x values (1,'AAAA')
insert @x values (1,'BBBB')
insert @x values (1,'CCCC')
insert @x values (2,'aa')
insert @x values (3,'abc')
insert @x values (3,'123')

SELECT
    a.RowID,
    STUFF(
             (
                SELECT ', '+b.x
                   FROM @x b
                   WHERE a.RowID=b.RowID
                   order by b.x
                   FOR XML PATH('') 
             ), 1, 2, ''
         ) AS ColName
    FROM @x a
    GROUP BY a.RowID

輸出:

RowID       ColName
----------- -----------------
1           AAAA, BBBB, CCCC
2           aa
3           123, abc

(3 row(s) affected)

下面的TSQL可以解決問題,您只需要替換適當的列和表名

DECLARE @vString NVARCHAR(500)
SET @vString = ''
SELECT @vString = @vString + ColumnNameToConcatenate + ',' 
FROM TableToPickColumnFrom

SELECT SUBSTRING(@vString, 0, LEN(@vString) -1) AS ConcatenatedText

它還從字符串的末尾刪除結尾的,因此您將獲得:

值1,值2,值3

比:

值1,值2,值3,

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM