Техника запроса

1. pisarevEV 8 14.04.23 11:48 Сейчас в теме
есть таблица в 2 колонки:

организация * сотрудники
Фирма 1 * Иван Петров Ольга Иванова
Фирма 2 * Петр Петров
Фирма 3 * Олег Иванов Петр Петров Анна Петрова

тип значения "сотрудники" строка, разделитель - пробел

надо трансформировать к такому виду:
организация * сотрудники
Фирма 1 * Иван Петров
Фирма 1 * Ольга Иванова
Фирма 2 * Петр Петров
Фирма 3 * Олег Иванов
Фирма 3 * Петр Петров
Фирма 3 * Анна Петрова

как это сделать при помощи запроса?
По теме из базы знаний
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
4. spacecraft 14.04.23 12:14 Сейчас в теме
(1) в общем случае - никак. разделитель имен и "сотрудников" один и тот же.
Просто представьте, что появился сотрудник: Гассан Абдуррахман ибн Хоттаб. Это не два сотрудника, а один :)
Нужно структуру хранения переделывать.
6. pisarevEV 8 14.04.23 12:26 Сейчас в теме
(4) можно упросить: только имя и только фамилия, сотрудников из 3х "слов" нет
2. пользователь 14.04.23 11:55
Сообщение было скрыто модератором.
...
3. pisarevEV 8 14.04.23 11:57 Сейчас в теме
* это для визуального разделения колонок, переносов строки нет
5. Said-We 14.04.23 12:16 Сейчас в теме
(1) В вашем случае по нормальному НИКАК.
"Иван Петров Ольга Иванова" - может быть Иван это и фамилия и отчество. Далее идут "Петров Ольга", а потом ещё сотрудник Иванова это и фамилия и отчество.

Разделитель между сотрудниками должен быть другой. НЕ пробел.
7. pisarevEV 8 14.04.23 12:27 Сейчас в теме
(5) структура входных данных не может быть изменена, можно только упросить приняв, что только имя и фамилия (отчеств нет)
8. pisarevEV 8 14.04.23 12:29 Сейчас в теме
это внешние данных, которые надо принять и прочитать
9. user1936660 14.04.23 12:40 Сейчас в теме
(8)
которые надо
А какие тебе вообще известны методы обработки строк в запросе?
10. Sashares 34 14.04.23 12:43 Сейчас в теме
(8)Так прочитайте их без запроса.
11. pisarevEV 8 14.04.23 12:45 Сейчас в теме
(10) очень много... (миллионы строк) без запроса никак
12. user1936660 14.04.23 12:46 Сейчас в теме
23. gybson 14.04.23 13:25 Сейчас в теме
(11) в запрос нельзя вставить текст на миллионы строк, необходимо преобразовать в ТЗ
Но если будет ТЗ, то запрос уже не нужен.
24. pisarevEV 8 14.04.23 13:27 Сейчас в теме
(23) миллионы записей в таб прошу прощения, не очень корректно написал
13. Said-We 14.04.23 12:47 Сейчас в теме
(11) В MS SQL есть такое и не только в нем:
SEL ECT * FR OM STRING_SPLIT('Lorem ipsum dolor sit amet.', ' ', 1);

SEL ECT ProductId, Name, value  
FR OM Product  
    CROSS APPLY STRING_SPLIT(Tags, ',');

Раз источник внешний, то прежде чем передать, можно чуть-чуть преобразовать не средствами 1С.
https://learn.microsoft.com/ru-RU/sql/t-sql/functions/string-split-transact-sql
Прикрепленные файлы:
14. user1936660 14.04.23 12:50 Сейчас в теме
15. pisarevEV 8 14.04.23 12:51 Сейчас в теме
(13) не получается у меня split... собственно поэтому и обратился сюда... да даже если и получится, что потом? одного сплита здесь явно не достаточно
26. mkalimulin 1129 14.04.23 13:54 Сейчас в теме
(15) Потом нумерация и соединение нечетных с четными
27. pisarevEV 8 14.04.23 13:56 Сейчас в теме
(26) теория мне ясна, не могу написать соотвествующий запрос
31. Said-We 14.04.23 15:55 Сейчас в теме
(26)
Потом нумерация и соединение нечетных с четными

Рекурсией можно сразу получать нужные пары. Но так писать в 29 не стал. Если что, то объяснять дольше.

(30) Если ФИ более 50 человек в строке, то рекурсия на MS SQL может не пройти (на SQLite проще там рекурсивный запрос и 300 вложенность глотает). На MS SQL и для более 50 человек есть решение, которое даже запрос 1С "смогёт", но не стоит. Там километровый запрос. Если данных много, то работает не быстро.
16. Said-We 14.04.23 12:54 Сейчас в теме
Далее у вас будет слова с номерами слов 1 и 2 их надо будет вместе соединить.
У STRING_SPLIT есть третий параметр. Он добавляет колонку с номером слова.
17. pisarevEV 8 14.04.23 12:56 Сейчас в теме
(16) прошу прощения конечно, но теория мне вполне ясна, трудности с практикой
18. Said-We 14.04.23 12:57 Сейчас в теме
Покажите что у вас получилось.
19. pisarevEV 8 14.04.23 12:59 Сейчас в теме
(18) SEL ECT * FR OM SPLIT(tab,' ')

и это не работает....
20. Said-We 14.04.23 13:04 Сейчас в теме
А если так:
SEL ECT <КолонкаСФирмой>, <ИмяКолонкиФИОстрокой>, value  
FR OM tab  
    CROSS APPLY STRING_SPLIT(<ИмяКолонкиФИОстрокой>, ' ')
21. pisarevEV 8 14.04.23 13:08 Сейчас в теме
http://www.sql-tutorial.ru/ru/book_string_split_function.html

я это раз 10 перечитал во всех направлениях) не работает(
22. user1936660 14.04.23 13:14 Сейчас в теме
Подожди, сейчас тебе расскажут, как это делается на sqlite!
25. mkalimulin 1129 14.04.23 13:50 Сейчас в теме
(21) Не делит на части? Или что-то другое? Должно работать, начиная с MS SQL 2016
28. user1936660 14.04.23 14:08 Сейчас в теме
(25)
начиная с MS SQL 2016
,Ну наконец-то, пошли робкие попытки уточнения - и откуда ж автор данные-то берет?
29. Said-We 14.04.23 14:17 Сейчас в теме
Можно рекурсией. Но есть ограничение. В MS SQL обычно стоит не более 100 вложенностей.
Под рукой сейчас только SQLite, но суть та же.
vt_data - ваши входные данные, но плюс пробел в конце строки. Пробел это у вас к сожалению разделитель.
vt - это обычный рекурсивный запрос разбивает на слова вашу строку
Итоговый собирает Фамилию+Имя по принципу четный и не четный: 1+2, 3+4, 5+6 и т.д.
WITH vt_data as
(SEL ECT t.f as f, t.str||' ' as str 
FR OM
	(SEL ECT 'Фирма 1' as f, 'Иван Петров Ольга Иванова' as str
	UNI ON ALL SEL ECT 'Фирма 2', 'Петр Петров'
	UNI ON ALL SELECT 'Фирма 3', 'Олег Иванов Петр Петров Анна Петрова'
	) as t
)

, vt as
(SELECT
	 t.f
	,substr(t.str, instr(t.str, ' ')+1) as str
	,substr(t.str, 0, instr(t.str, ' ')) as slovo
	,1 as npp
FR OM
	vt_data as t
	
uni on ALL

SEL ECT
	 t.f
	,substr(t.str, instr(t.str, ' ')+1)
	,substr(t.str, 0, instr(t.str, ' '))
	,t.npp + 1 as npp
FR OM vt as t
WH ERE instr(t.str, ' ')<>0
)

SEL ECT t.f as f, t.FI as FI
FR OM
	(SEL ECT
		 t.f as f
		,t.slovo || ' ' || LEAD(t.slovo) over(PARTITION by t.f ORDER by t.npp) as FI
		,t.npp as npp
	FR OM
		vt as t
	) as t
WH ERE t.npp%2<>0
ORDER by t.f, t.npp

Результат
f	                FI
Фирма 1	Иван Петров
Фирма 1	Ольга Иванова
Фирма 2	Петр Петров
Фирма 3	Олег Иванов
Фирма 3	Петр Петров
Фирма 3	Анна Петрова
Показать
30. pisarevEV 8 14.04.23 14:22 Сейчас в теме
(29) ок, попробую разобраться
32. Said-We 15.04.23 21:28 Сейчас в теме
(30)
ок, попробую разобраться

Получилось?
33. pisarevEV 8 16.04.23 00:46 Сейчас в теме
(32)
нет... на самом деле проблема не в коде запроса... проблема в "среде"... я пытаюсь сделать запрос в PySpark, там немного другой синтаксис sql, и вот как раз на этой задаче не работает... пока не могу найти спеца по PySpark)
34. пользователь 16.04.23 10:52
Сообщение было скрыто модератором.
...
35. Said-We 16.04.23 12:18 Сейчас в теме
(33)
я пытаюсь сделать запрос в PySpark

А вы вот это где исполнить пытались?
SEL ECT * FR OM SPLIT(tab,' ')
36. pisarevEV 8 17.04.23 10:16 Сейчас в теме
(35) в pyspark, просто думал что я что-то не так делаю по логике запроса, но видимо дело в нюансах синтаксиса
37. Said-We 17.04.23 12:22 Сейчас в теме
(36) Это тот, в котором вот такой синтаксис?
# Выбор одного столбца
data.sel ect('sector').show(5)

# Выбор нескольких столбцов
data.select(['open', 'close', 'adjusted']).show(5)

# Использование CASE WHEN в PySpark
sql = """
CASE
    WHEN (lang LIKE 'c') OR (lang LIKE 'cpp') THEN 'C/C++'
    WHEN (lang LIKE 'py') THEN 'Python'
    ELSE 'unknown'
END"""
df.withColumn('FullLang', F.expr(sql)).show()

# Использование JOIN в PySpark
df.join(df2, df.name == df2.name, 'outer').select(df.name, df2.height).sort(desc("name")).show()
Показать

Этот вот так примерно будет в нем выглядеть рекурсивный запрос:
# Loop Through if you dont know recusrsive depth
while True:
  this_level = 'level_{}'.format(i)
  next_level = 'level_{}'.format(i+1)
  emp_level = employees \
    .withColumnRenamed('EMPLOYEE_NUMBER', this_level) \
    .withColumnRenamed('MANAGER_EMPLOYEE_NUMBER', next_level)
  empDF = empDF.join(emp_level, on=this_level, how='left')
  
  # Check if DF is empty. Break loop if empty, Otherwise continue with next level
  if empDF.where(col(next_level).isNotNull()).count() == 0:
    break
  else:
    i += 1

# Sort columns and show
empDF.sort('level_0').select('level_0').show()
Показать

Извини, но это даже на SPARK SQL с точки зрения синтаксиса.
spark.sql("select lang fr om prog_info").show()

В pyspark это не запросы, а как в БСП набор каких-то функций работы с данными.
Pyspark больше похож на процедурную пошаговую работу с данными. С 1С можно сравнить как выгрузить всё в разные ТЗ и потом средствами БСП с этими данными что-то делать.
К формулировке в (1) "как это сделать при помощи запроса?", это не имеет никакого отношения.

Лучше скажи. Где эти данные физически лежат, как приходят, куда и в каком виде.
38. pisarevEV 8 17.04.23 13:38 Сейчас в теме
так вот в том то и проблема что даже такой примитивный код не работает:

sc = SparkSession.builder.appName('test').getOrCreate()
sc.sql("SEL ECT * FR OM SPLIT("f f f f f"," ")").show()
40. spacecraft 17.04.23 14:37 Сейчас в теме
(38)
sc.sql("SEL ECT * FR OM SPLIT("f f f f f"," ")").show()

За кавычками следили?
"SEL ECT * FR OM SPLIT(" - строка кода sql. Дальше непойми что.
42. pisarevEV 8 17.04.23 16:07 Сейчас в теме
(40)
без сокращений:


df=sc.sql("""
SEL ECT * FR OM SPLIT('f f f f f',' ')
""")

ошибка:
could not resolve `SPLIT` to a table-valued function;

в учебнике:
SEL ECT * FR OM STRING_SPLIT('0 1 2 3 4 5 6 7 8 9',' ');
49. spacecraft 17.04.23 16:49 Сейчас в теме
(42)
в учебнике:

В каком учебнике и по какому языку?

df=sc.sql("SELECT SPLIT('f f f f f',' ') as Array")
53. pisarevEV 8 17.04.23 17:23 Сейчас в теме
(49)
df=sc.sql("SELECT SPLIT('f f f f f',' ') as Array")


это мне никак не поможет, хотя код работает... код преобразует текст (строку) в массив слов, но мне нужно не это
55. spacecraft 17.04.23 17:31 Сейчас в теме
(50) (53) это просто рабочий вариант вместо того, что пытались сделать. То что пытались сделать не то и "это мне никак не поможет" без комментариев.

Просто поймите, что pyspark не поддерживает полное соответствие t-sql. Там "запрос" чем то напоминает его, но не полностью соответствует. И это вообще вторично там. В основном предполагается работа с объектной моделью данных. Вот это там очень мощный инструмент с лямбда выражениями.
Но не стоит напрямую натягивать язык t-sql на pyspark.
56. pisarevEV 8 17.04.23 17:53 Сейчас в теме
(55)все верно, я хотел решить в 2 этапа... сначала используя синтаксис sql (просто более понятен) а потом переписать на "родном" языке ps... но не могу в итоге даже сплит элементарный сделать(
57. spacecraft 17.04.23 18:26 Сейчас в теме
(56) это как учить язык запросов в 1С используя синтаксис sql. Что-то будет работать, но половина просто не подойдет.
pisarevEV; +1 Ответить
39. Said-We 17.04.23 13:43 Сейчас в теме
(38) Где эти данные физически лежат, как приходят, куда и в каком виде?
43. pisarevEV 8 17.04.23 16:08 Сейчас в теме
41. Said-We 17.04.23 15:40 Сейчас в теме
(40) Предположу, что так у автора кавычки нормально съест:
sc.sql("SEL ECT * FR OM SPLIT('f f f f f',' ')").show() 

Могу ошибаться, но писал бы в части кавычек изначально так, либо, если строка длинная, то отдельно строку запроса, а в коде её просто использовать.
44. pisarevEV 8 17.04.23 16:10 Сейчас в теме
более сложный вариант:

df=sc.sql("""
SEL ECT
original_title,
cast,
value
FR OM
tab
CROSS APPLY SPLIT(cast,' ');
""")
ошибка:
Syntax error at or near 'APPLY': missing 'JOIN'

аналог из учебника:
SEL ECT name, value FR OM Ships CROSS APPLY STRING_SPLIT(name,' ')
45. Said-We 17.04.23 16:16 Сейчас в теме
(43)
1. Это разовая операция?
2. Чем обусловлено желание затащить данные, в том виде как они прилетают, и не возможность их предварительно переработать?

(44)
Ругается же не на STRING_SPLIT. Говорит что используйте JOIN.
46. pisarevEV 8 17.04.23 16:19 Сейчас в теме
(45) это я вижу) только где место для join в этом запросе?
47. pisarevEV 8 17.04.23 16:20 Сейчас в теме
(45) да я их уже затащил давно стандартными инструментами чтение csv... просто это индуский подход...хочется красиво)
48. Said-We 17.04.23 16:38 Сейчас в теме
(47) Куда затащили? Вы пытаетесь выполнить "не индуским" подходом, но не обращаете никакого внимания на текущие возможности вашей системы. Более того, скрываете до последнего, где и что вы делаете. :-) Что бы другие гадали, что и где вы делаете.
Если уже затащили и это разовая операция, тогда забудьте.
51. pisarevEV 8 17.04.23 17:20 Сейчас в теме
(48)критика принимается) акция разовая, интерес чисто академический)
52. Said-We 17.04.23 17:23 Сейчас в теме
(50) Вы пытаетесь синтаксис MS SQL в чистом виде применить в другом синтаксисе.
Да все SQL языки очень сильно похожи, но не на столько же, что можно брать без адаптации код из одного и рисовать в другом.
54. pisarevEV 8 17.04.23 17:24 Сейчас в теме
(52)в точку, не могу найти спеца профильного(
58. user1880116 17.04.23 21:46 Сейчас в теме
(52)
брать без адаптации код из одного и рисовать в другом.
Однако, это совсем не мешает некоторым приводить код для sqlite в ответ на вопрос о языке запросов 1С.
59. user1826630 17.04.23 22:02 Сейчас в теме
(58) коллега, вы щас про клюшки?
60. user1880116 17.04.23 22:31 Сейчас в теме
61. user1826630 17.04.23 22:34 Сейчас в теме
(60) Говорят, что в хоккее у клюшек должен правильно загнут конец. Иначе - удаление!
62. user1880116 17.04.23 22:38 Сейчас в теме
(61) Мало того, что загнут... Ещё должен быть обмотан правильной изолентой, иначе щелчок не получается.
63. user1826630 17.04.23 22:48 Сейчас в теме
(62) Durex? Contex? Витязь, Гусар и проч?
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот