Объединение нескольких результатов в подзапрос в единое значение, разделенное запятыми
У меня есть две таблицы:
TableA
------
ID,
Name
TableB
------
ID,
SomeColumn,
TableA_ID (FK for TableA)
Отношение - это одна строка TableA
- многие из TableB
.
Теперь я хочу увидеть результат следующим образом:
ID Name SomeColumn
1. ABC X, Y, Z (these are three different rows)
2. MNO R, S
Это не сработает (несколько результатов в подзапросе):
SELECT ID,
Name,
(SELECT SomeColumn FROM TableB WHERE F_ID=TableA.ID)
FROM TableA
Это тривиальная проблема, если я выполняю обработку на стороне клиента. Но это будет означать, что мне нужно будет запускать X запросов на каждой странице, где X - количество результатов TableA
.
Обратите внимание, что я не могу просто выполнить GROUP BY или что-то подобное, поскольку оно вернет несколько результатов для строк TableA
.
Я не уверен, может ли работать UDF, используя COALESCE или что-то подобное?
Ответы
Ответ 1
1. Создайте UDF:
CREATE FUNCTION CombineValues
(
@FK_ID INT -- The foreign key from TableA which is used
-- to fetch corresponding records
)
RETURNS VARCHAR(8000)
AS
BEGIN
DECLARE @SomeColumnList VARCHAR(8000);
SELECT @SomeColumnList =
COALESCE(@SomeColumnList + ', ', '') + CAST(SomeColumn AS varchar(20))
FROM TableB C
WHERE C.FK_ID = @FK_ID;
RETURN
(
SELECT @SomeColumnList
)
END
2. Использовать в подзапросе:
SELECT ID, Name, dbo.CombineValues(FK_ID) FROM TableA
Ответ 2
Даже это будет служить цели
Примеры данных
declare @t table(id int, name varchar(20),somecolumn varchar(MAX))
insert into @t
select 1,'ABC','X' union all
select 1,'ABC','Y' union all
select 1,'ABC','Z' union all
select 2,'MNO','R' union all
select 2,'MNO','S'
Query:
SELECT ID,Name,
STUFF((SELECT ',' + CAST(T2.SomeColumn AS VARCHAR(MAX))
FROM @T T2 WHERE T1.id = T2.id AND T1.name = T2.name
FOR XML PATH('')),1,1,'') SOMECOLUMN
FROM @T T1
GROUP BY id,Name
Вывод:
ID Name SomeColumn
1 ABC X,Y,Z
2 MNO R,S
Ответ 3
Я думаю, что вы на правильном пути с COALESCE. См. Здесь пример построения строки с разделителями-запятыми:
http://www.sqlteam.com/article/using-coalesce-to-build-comma-delimited-string
Ответ 4
В MySQL есть функция group_concat, которая вернет то, о чем вы просите.
SELECT TableA.ID, TableA.Name, group_concat(TableB.SomeColumn)
as SomColumnGroup FROM TableA LEFT JOIN TableB ON
TableB.TableA_ID = TableA.ID
Ответ 5
Вам может потребоваться предоставить более подробную информацию для более точного ответа.
Поскольку ваш набор данных кажется довольно узким, вы можете рассмотреть возможность использования строки за результат и выполнения последующей обработки на клиенте.
Итак, если вы действительно хотите заставить сервер выполнить работу, верните результат, например
ID Name SomeColumn
1 ABC X
1 ABC Y
1 ABC Z
2 MNO R
2 MNO S
который, конечно же, является простым INNER JOIN на ID
После того, как у вас есть набор результатов на клиенте, сохраните переменную с именем CurrentName и используйте ее как триггер, когда прекратите сбор SomeColumn в полезную вещь, которую вы хотите сделать.
Ответ 6
Предполагая, что в таблице A есть только предложения WHERE, создайте хранимую процедуру таким образом:
SELECT Id, Name From tableA WHERE ...
SELECT tableA.Id AS ParentId, Somecolumn
FROM tableA INNER JOIN tableB on TableA.Id = TableB.F_Id
WHERE ...
Затем заполните DataSet ds. Тогда
ds.Relations.Add("foo", ds.Tables[0].Columns("Id"), ds.Tables[1].Columns("ParentId"));
Наконец, вы можете добавить ретранслятор на страницу, которая помещает запятые для каждой строки
<asp:DataList ID="Subcategories" DataKeyField="ParentCatId"
DataSource='<%# Container.DataItem.CreateChildView("foo") %>' RepeatColumns="1"
RepeatDirection="Horizontal" ItemStyle-HorizontalAlign="left" ItemStyle-VerticalAlign="top"
runat="server" >
Таким образом, вы будете делать это на стороне клиента, но только с одним запросом, передавая минимальные данные между базой данных и интерфейсом
Ответ 7
Я попробовал решение priyanka.sarkar, упомянутое, и он не совсем понял, как работает OP. Здесь решение, в котором я закончил:
SELECT ID,
SUBSTRING((
SELECT ',' + T2.SomeColumn
FROM @T T2
WHERE WHERE T1.id = T2.id
FOR XML PATH('')), 2, 1000000)
FROM @T T1
GROUP BY ID
Ответ 8
Решение ниже:
SELECT GROUP_CONCAT(field_attr_best_weekday_value)as RAVI
FROM content_field_attr_best_weekday LEFT JOIN content_type_attraction
on content_field_attr_best_weekday.nid = content_type_attraction.nid
GROUP BY content_field_attr_best_weekday.nid
Используйте это, вы также можете изменить Joins
Ответ 9
Я просмотрел все ответы. Я думаю, что вставка базы данных должна быть такой:
ID Name SomeColumn
1. ABC ,X,Y Z (these are three different rows)
2. MNO ,R,S
Запятая должна быть на предыдущем конце и выполнять поиск, как %,X,%
Ответ 10
SELECT t.ID,
t.NAME,
(SELECT t1.SOMECOLUMN
FROM TABLEB t1
WHERE t1.F_ID = T.TABLEA.ID)
FROM TABLEA t;
Это будет работать для выбора из другой таблицы с использованием суб-запроса.