Разделена колона с разделени стойности за вътрешно съединение

Трябва да извърша вътрешно присъединяване към колона, съдържаща разделени стойности като:

123;124;125;12;3433;35343;

Сега това, което правя в момента, е следното:

ALTER procedure [dbo].[GetFruitDetails]
(
    @CrateID int
)
AS

SELECT Fruits.*, Fruits_Crates.CrateID 
    FROM Fruits_Crates INNER JOIN Fruits 
    ON Fruits_Crates.FruitID = Fruits.ID
    WHERE Fruits_Crates.CrateID = @CrateID

Сега проблемът е, че запазвам данните по този начин:

FruitCrateID  FruitID 
1             1;
2             1;2;3;4
3             3;

Как мога да присъединя вътрешно FruitsIDs към таблицата с плодове, за да получа и подробности за плодовете?


person Mathematics    schedule 10.11.2014    source източник
comment
Действителният проблем е, че съхранявате множество стойности в една колона, което никога не трябва да правите. Можете ли да направите своя дизайн на масата?   -  person juergen d    schedule 10.11.2014
comment
@juergend да, мога, но тогава имам друг проблем, който е описан тук, stackoverflow.com/questions/25869110/   -  person Mathematics    schedule 10.11.2014
comment
Можете да опитате нещо като ... @multi_value КАТО '%;'+FruitID+';%'. За скоби можете да добавите комбинации '(%'+... или просто да получите стойности в друг формат, напр. ;123;124;125;12;. Въпреки това е по-добре да промените дизайна на DB.   -  person i486    schedule 10.11.2014
comment
@CustomizedName Отговорът в публикацията, която маркирах като дубликат, трябва да работи за вас, въпреки че промяната на дизайна, както предложи juergen d, може да е по-добра идея.   -  person jpw    schedule 10.11.2014


Отговори (1)


Използване на метода, публикуван в този отговор, можете да конвертирате разделения низ в редове на временна таблица и след това да се присъедините към това:

SQL Fiddle

Настройка на схема:

CREATE TABLE Fruits_Crates
    ([FruitCrateID] int, [FruitID] varchar(10))
;

INSERT INTO Fruits_Crates
    ([FruitCrateID], [FruitID])
VALUES
    (1, '1;'),
    (2, '1;2;3;4;'),
    (3, '3;')
;

CREATE TABLE Fruits
    ([FruitID] int, [FruitName] varchar(10))
;

INSERT INTO Fruits
    ([FruitID], [FruitName])
VALUES
    (1, 'Apple'),
    (2, 'Banana'),
    (3, 'Orange'),
    (4, 'Pear')
;

Вмъкване във временна таблица:

 SELECT A.[FruitCrateID],  
     Split.a.value('.', 'VARCHAR(100)') AS FruitId  
 INTO #fruits
 FROM  (SELECT [FruitCrateID],  
         CAST ('<M>' + REPLACE([FruitID], ';', '</M><M>') + '</M>' AS XML) AS String  
     FROM  Fruits_Crates) AS A CROSS APPLY String.nodes ('/M') AS Split(a)

Присъединете се към временна таблица за търсене:

SELECT t1.*, t2.FruitName
FROM #Fruits t1
INNER JOIN Fruits t2 on t1.FruitId = t2.FruitId

Резултати:

| FRUITCRATEID | FRUITID | FRUITNAME |
|--------------|---------|-----------|
|            1 |       1 |     Apple |
|            2 |       1 |     Apple |
|            2 |       2 |    Banana |
|            2 |       3 |    Orange |
|            2 |       4 |      Pear |
|            3 |       3 |    Orange |
person Tanner    schedule 10.11.2014
comment
Ще опитам да променя дизайна на базата данни и след това да използвам вместо това параметър със стойност на таблица c#, но мисля, че отговорът ви също е правилен, благодаря :) - person Mathematics; 10.11.2014
comment
@CustomizedName да, промяната на дизайна е правилното нещо, което трябва да направите. - person Tanner; 10.11.2014