Я попытался с помощью combByKey, вот мои шаги
combineddatardd=sc.parallelize([("A", 3), ("A", 9), ("A", 12),("B", 4), ("B", 10), ("B", 11)])
combineddatardd.combineByKey(lambda v:[v],lambda x,y:x+[y],lambda x,y:x+y).collect()
Выход:
[('A', [3, 9, 12]), ('B', [4, 10, 11])]
Взгляните на эту функцию. Я сделал аналогичные трюки для разделения и переноса данных в Oracle. Переверните данные, вставляя декодированные значения в временную таблицу. Конфликт в том, что MS позволит вам сделать это «на лету», в то время как Oracle требует явной таблицы temp.
Функция разделения MS SQL Функция лучшего разделения
Редактировать автор: Это сработало отлично. Окончательный код выглядел так (после создания функции split):
select pv.productid, colortable.items as color
from product p
cross apply split(p.color, ',') as colortable
Я бы создал для этой функции CLR-таблицу:
http://msdn.microsoft.com/en-us/library/ms254508 (VS.80) .aspx
Причиной этого является то, что код CLR будет намного лучше разбирать строки (вычислительную работу) и может передать эту информацию в виде набора, что действительно является SQL Server
Функция CLR вернет серию записей на основе проанализированных значений (и значения входного идентификатора).
Затем вы использовали бы КРЕСТНОЕ ПРИМЕНЕНИЕ на каждый элемент вашей таблицы.
Вы можете попробовать это, не требуя каких-либо дополнительных функций:
declare @t table (col1 varchar(10), col2 varchar(200)) insert @t select '1', 'red,blue,green' union all select '2', NULL union all select '3', 'green,purple' select col1, left(d, charindex(',', d + ',')-1) as e from ( select *, substring(col2, number, 200) as d from @t col1 left join (select distinct number from master.dbo.spt_values where number between 1 and 200) col2 on substring(',' + col2, number, 1) = ',') t
Исправить вашу базу данных, если это вообще возможно. Списки с разделителями-запятыми в ячейках базы данных указывают на ошибочную схему в 99% случаев или более.
на основе ваших таблиц:
create table test_table
(
ProductId int
,Color varchar(100)
)
insert into test_table values (1, 'red, blue, green')
insert into test_table values (2, null)
insert into test_table values (3, 'purple, green')
создать новую таблицу следующим образом:
CREATE TABLE Numbers
(
Number int not null primary key
)
, которая имеет строки, содержащие значения от 1 до 8000 или около того.
это вернет вам то, что вы хотите:
EDIT вот намного лучший запрос, слегка измененный из большого ответа от @Christopher Klein:
Я добавил «LTRIM () «поэтому пробелы в списке цветов будут обработаны правильно:« красный, синий, зеленый ». Его решение не требует пробелов «красный, синий, зеленый». Кроме того, я предпочитаю использовать свою собственную таблицу Number и не использовать master.dbo.spt_values, это также позволяет удалить одну производную таблицу.
SELECT
ProductId, LEFT(PartialColor, CHARINDEX(',', PartialColor + ',')-1) as SplitColor
FROM (SELECT
t.ProductId, LTRIM(SUBSTRING(t.Color, n.Number, 200)) AS PartialColor
FROM test_table t
LEFT OUTER JOIN Numbers n ON n.Number<=LEN(t.Color) AND SUBSTRING(',' + t.Color, n.Number, 1) = ','
) t
EDIT END
SELECT
ProductId, Color --,number
FROM (SELECT
ProductId
,CASE
WHEN LEN(List2)>0 THEN LTRIM(RTRIM(SUBSTRING(List2, number+1, CHARINDEX(',', List2, number+1)-number - 1)))
ELSE NULL
END AS Color
,Number
FROM (
SELECT ProductId,',' + Color + ',' AS List2
FROM test_table
) AS dt
LEFT OUTER JOIN Numbers n ON (n.Number < LEN(dt.List2)) OR (n.Number=1 AND dt.List2 IS NULL)
WHERE SUBSTRING(List2, number, 1) = ',' OR List2 IS NULL
) dt2
ORDER BY ProductId, Number, Color
вот мой результирующий набор:
ProductId Color
----------- --------------
1 red
1 blue
1 green
2 NULL
3 purple
3 green
(6 row(s) affected)
, который тот же самый порядок вы хотите ...
Просто конвертируйте свои столбцы в xml и запросите его. Вот пример.
select
a.value('.', 'varchar(42)') c
from (select cast('<r><a>' + replace(@CSV, ',', '</a><a>') + '</a></r>' as xml) x) t1
cross apply x.nodes('//r/a') t2(a)
CROSS APPLY STRING_SPLIT(p.color, ',')
– Dave 18 October 2016 в 20:23