#sql-server #tsql
Вопрос:
Я занимаюсь этим уже несколько часов, пытаясь разобраться в этом. Поэтому мне нужно объединить значения в один столбец на основе его идентификаторов.
У меня есть 3 таблицы с именами Тип, Тип доставки и платформа. Мне нужно получить все соответствующие идентификаторы в табличной платформе и объединить все их значения в другом столбце табличной платформы.
Пример :
Table Type Table DeliverType Table Platform
----------------------------------------------------------------------------------------
ID | Type ID | DeliverType ID | TypeID | DeliverType
----------------------------------------------------------------------------------------
1 | TestType1 1 | DeliverType1 9 | 3 | 1
2 | TestType2 2 | DeliverType2 9 | 4 | 2
3 | TestType3 3 | DeliverType3 23 | 2 | 4
4 | TestType4 4 | DeliverType4 23 | 1 | 3
Это мои таблицы , я хочу вернуть имя типа, имя типа доставки и идентификатор платформы
ожидаемый результат
Table Platform
ID | NamesConcat
9 | TestType1,TestType2,TestType3,DeliverType1,DeliverType2,9
23 | TestType2,TesType3,TestType4,DeliverType3,DeliverType4,23
Таким образом, у него есть только 1 идентификатор, равный 9, и все типы тестов и типы доставки, соответствующие этому идентификатору в таблице, должны быть объединены.
Вот мой код до сих пор:
SELECT DISTINCT p.ID,
SUBSTRING(
(
SELECT ',' d.DeliverType,a.Type AS [text()]
FROM dbo.DeliverType d
INNER JOIN dbo.Type a ON a.ID = p.TypeID
ORDER BY d.ID
FOR XML PATH ('')
), 2, 1000) [NamesConcat]
FROM dbo.Platform p
Был бы признателен за некоторую помощь в этом коллегам-программистам.
Заранее большое вам спасибо.
Ответ №1:
Из приведенных вами примеров данных я не получаю того же ожидаемого результата. Я бы ожидал результата:
Настольная Платформа
ID | NamesConcat |
---|---|
9 | Тип теста3,тип теста4,тип доставки1,тип доставки2,9 |
23 | Тип теста1,тип теста2,тип доставки 3,тип доставки 4,23 |
Если это действительно ожидаемый результат и вы хотите, чтобы строки были объединены Type
первым, а затем DeliverType
вторым, вы можете сделать это с помощью этого запроса:
SELECT DISTINCT pmain.ID,
(
SELECT t.[Type] ','
FROM Platform p
INNER JOIN Type t ON t.ID = p.TypeID
WHERE p.ID = pmain.ID
ORDER BY t.ID
FOR XML PATH('')
)
(
SELECT d.DeliverType ','
FROM Platform p
INNER JOIN DeliverType d ON d.ID = p.DeliverTypeID
WHERE p.ID = pmain.ID
ORDER BY p.ID
FOR XML PATH('')
)
CAST(pmain.ID AS VARCHAR(10)) AS NamesConcat
FROM Platform pmain
Если вам не нужны объединенные значения в таком порядке, вы можете сделать это с помощью более короткого запроса:
SELECT DISTINCT pmain.ID,
(
SELECT d.DeliverType ',' t.[Type] ','
FROM Platform p
INNER JOIN DeliverType d ON d.ID = p.DeliverTypeID
INNER JOIN Type t ON t.ID = p.TypeID
WHERE p.ID = pmain.ID
FOR XML PATH('')
) CAST(pmain.ID AS VARCHAR(10)) AS NamesConcat
FROM Platform pmain
Чтобы вы могли проверить работу, вот простой скрипт, который я написал, чтобы имитировать ваши демонстрационные данные и результат:
DECLARE @Type AS TABLE (
ID INT IDENTITY(1,1) NOT NULL,
[Type] VARCHAR(20) NOT NULL
);
INSERT INTO @Type([Type]) VALUES('TestType1'), ('TestType2'), ('TestType3'), ('TestType4');
DECLARE @DeliverType AS TABLE (
ID INT IDENTITY(1, 1) NOT NULL,
[DeliverType] VARCHAR(25) NOT NULL
);
INSERT INTO @DeliverType([DeliverType]) VALUES ('DeliverType1'), ('DeliverType2'), ('DeliverType3'), ('DeliverType4');
DECLARE @Platform AS TABLE (
ID INT NOT NULL,
TypeID INT NOT NULL,
DeliverTypeID INT NOT NULL
);
INSERT INTO @Platform(ID, TypeID, DeliverTypeID) VALUES (9, 3, 1), (9, 4, 2), (23, 2, 4), (23, 1, 3);
SELECT DISTINCT pmain.ID,
(
SELECT d.DeliverType ',' t.[Type] ','
FROM @Platform p
INNER JOIN @DeliverType d ON d.ID = p.DeliverTypeID
INNER JOIN @Type t ON t.ID = p.TypeID
WHERE p.ID = pmain.ID
FOR XML PATH('')
) CAST(pmain.ID AS VARCHAR(10)) AS NamesConcat
FROM @Platform pmain
SELECT DISTINCT pmain.ID,
(
SELECT t.[Type] ','
FROM @Platform p
INNER JOIN @Type t ON t.ID = p.TypeID
WHERE p.ID = pmain.ID
ORDER BY t.ID
FOR XML PATH('')
)
(
SELECT d.DeliverType ','
FROM @Platform p
INNER JOIN @DeliverType d ON d.ID = p.DeliverTypeID
WHERE p.ID = pmain.ID
ORDER BY p.ID
FOR XML PATH('')
)
CAST(pmain.ID AS VARCHAR(10)) AS NamesConcat
FROM @Platform pmain
Я надеюсь, что это то, что вы искали!
Комментарии:
1. Ты-спаситель. Большое спасибо. Не могли бы вы, пожалуйста, объяснить различия между pmain и p? Остальную часть кода я понял прекрасно.
2. Конечно! Поскольку мы присоединяемся к подзапросу, платформа таблицы используется дважды. Мы должны создать псевдоним таблицы, чтобы SQL Server (или любая другая СУБД) не запуталась. Я называю самый внешний псевдоним pmain (не творческий, но он у вас есть — таблица платформы в основном запросе). В подзапросах я использую псевдоним p (очень ленивый, я знаю…). Когда я соединяю основной запрос с подзапросом, я хочу сопоставить основное значение идентификатора с платформы (pmain. ИДЕНТИФИКАТОР) к идентификатору платформы в подзапросе (p.ID).
3. О , теперь я все понял! Большое тебе спасибо , чувак, ты действительно спаситель.