Навеяно неоднократными вопросами об изменении порядка строк после выполнения функции, например этой
Цитата
Михаил Л написал: Впору в курилке создать тему про функции PQ, которые не ведут себя однозначно при разных количествах строк.
хм... Насколько мне известно, все функции ведут себя однозначно, но порядок строк таблицы может меняться, если применена какая-то функция групповой обработки строк.
точно не гарантирует сохранение порядка строк:
глобальная группировка
удаление дубликатов
слияние/join/merge (практически любой вариант слияния)
Скорее всего, не гарантирует порядок строк
удаление дубликатов списка (List.Distinct) (но не проверял, х.з., не помню, почему мне так кажется, но кажется логичным).
разворачивание структурного столбца в новые строки:
Table.ExpandRecordColumn (столбец записей),
Table.ExpandListColumn (столбец списков),
Table.ExpandTableColumn столбец таблиц)
Локальная группировка, по идее, должна сохранять порядок строк, но не сильно удивлюсь, если при правильно проведенной локальной группировке порядок вывода результата будет отличаться от начального.
Иногда с этим можно бороться, фиксируя/пересчитывая таблицу в памяти перед операцией (например, добавлением индекса). Может, еще что-то вспомню
Максим Зеленский написал: точно не гарантирует сохранение порядка строк: глобальная группировка удаление дубликатов слияние/join/merge (практически любой вариант слияния)
Наверное надо упомянуть какие действия (ссылка) сохранят порядок строк, например, для удаления дубликатов достаточно, перед удалением дубликатов, обернуть таблицу в Table.Buffer. И пример
Михаил Л, а чего он не так перевёл? Все ровно так как написал Эрен. Можно ещё косяк sort+distinct обозвать как collaterial damage. Или, говоря по-русски: Лес рубят - щепки летят.
Недавно имел очень любопытную дискуссию с хорошим специалистом по PQ, в результате которой родилась следующая цепочка рассуждений и утверждений:
Сами по себе функции типа Table.Distinct или List.Distinct не являются тем, кто меняет порядок строк в таблице/списке. Так, скорее всего, на статичных источниках данных (типа явных перечислений или явно заданных таблицах, или других) не удается подтвердить изменение порядка строк для этих функций.
В основном всё упирается в то, включается ли стриминговая семантика для конкретного источника данных. Если да (источник с потенциально изменяемым порядком строк), то тогда, при выполнении функции, за счет стриминга в нее может подаваться переменный набор строк (т.е. в другом порядке, даже если количество строк не изменилось).
Некоторые функции действительно могут менять порядок строк в таблице - это функции группировки и слияния (merge/join). Об этом, как правило, написано в документации, но да, для обычного пользователя (особенно родом из Excel) это вообще не очевидно.
В любом случае хорошее правило: Если для каких-то целей важен порядок строк, его необходимо явно задать и загнать таблицу в буфер перед операцией, или обеспечить восстановление нужного порядка после операции.
по подтверждению одного из разработчиков, также сохранение порядка не гарантировано (иногда может помочь List.Buffer, но зависит от источника данных, из которого этот список пришел)
А меня раздражает в PQ, что сбрасываются типы столбцов после некоторых операций, после чего нужно опять всё восстанавливать. Плюс не в Office 365 нет IntelliSense. Этот как в 80-е годы набирали код в командной строке.
SuperCat написал: сбрасываются типы столбцов после некоторых операций
В основном слетают типы, когда вы например, разворачиваете вложенные таблицы. Не так чтобы сильно давно, но уже давненько ввели сохранение типа столбцов при группировке с агрегацией "Все строки" - теперь типы прямо прописываются в коде и не слетают при разворачивании. Если вы получили вложенную таблицу другими способами, то там тоже есть подходы. Например, прописать возвращаемый тип в функции, которая делает таблицу, и т.п.
Да, проглядел. Надстройка PQ уже давненько не обновлялась, отстает примерно на 20 релизов В 2016-2019 тоже отстает, не знаю, на сколько версий. Но можно использовать Visual Studio Code, там есть полная поддержка Power Query - с интеллисенсом, даж со справкой - всё как внутри. Плюс поиск, массовая замена и всё как мы любим в Code
После темы с Type time bug я уже этому не удивляюсь. Его вопросы тогда я так и не понял, хотя ему аж три русских человека английскими буквами все написали с табличками и примерами. Ладно, я коряво изъясняюсь, но у вас и второго нашего соотечественника явно скилл в ангельском заметно выше. А он пометил тему как решенную и был таков. Красавчег. Не знаю что там за помутнение на него напало, обычно вполне адекватный гражданин.
как-то бесчеловечно. А команда разработчиков, полагаю, и не собирается исправлять этот баг Вполне возможно, из команды свалили математики, которые сформировали каркас оптимизатора (упростителя выражений).
Андрей VG, про это в курсе, но опять же, как писал выше Максим, это работает только потому что: "так получилось". И гарантировать что такое будет работать и дальше никто не может.
без ошибки. И да, при удалении сортировки, или размещении ее после шага maxPartWithoutBuffer (что не имеет смысла, конечно) - всё работает... Странный глюк. Очевидно, связан с сочетанием сортировки и Table.FirstN. Заброшу команде разработки, посмотрим, что они скажут
Андрей VG написал: из команды свалили математики, которые сформировали каркас оптимизатора
х.з... я знаю трех разрабов PQ - Ehren von Lehe, Curt Hagenlocher, Matt Masson - все на месте. Еще Miguel Llopis, но он скорее PM, а не разраб. Но кто был там еще и оставался непубличным - х.з. Курт как-то обмолвился, что "если бы делали сейчас - некоторые вещи делали бы по-другому", но это так, для истории
let
Source = Table.FromColumns({{"one", "two"}}, {"name"}),
trans1 = Table.TransformColumns(Source, {{"name", each _, Text.Type}}), // has not type text
trans2 = Table.TransformColumns(Source, {{"name", each _ & "", Text.Type}}) // has type text
in
trans2
Раз в trans1 мы ничего не делаем, то и тип столбцу присваивать не будем
Андрей VG, не думаю, что только в этом дело вот так работает, хотя мы ничего не делаем:
Код
= Table.TransformColumns(Source, {{"name", (_) as text=> _}})
Скорее всего (предполагаю на 80%) тип не присваивается только для each _ Но в любом случае, это не конвертация/проверка типа значений, а присвоение типа столбцу:
Код
= Table.TransformColumns(Source, {{"name", (_) as text=> _, type date}})
= Table.TransformColumns(Source, {{"name", each _ & "", type date}})
в обоих случаях даст тип столбца date, а в ячейках будет по-прежнему текст Вообще присвоение и проверка типов та еще история. Надо минимум полбанки, чтобы разобраться
let
Source = Table.FromRows({{"01.01.2020"}}, {"date1"}),
Typed = Table.TransformColumnTypes(Source,{{"date1", type date}}),
Added2Typed = Table.AddColumn(Typed, "date2", each [date1], type date),
ColumnsOfType = Table.ColumnsOfType(Added2Typed, {type date})
in
ColumnsOfType
не подглядывая, какие имена столбцов будут в списке?
нет, не косяки, а типичное буквоедство На самом деле настолько неочевидный момент, что только кропотливое изучение схемы дает ответ. В Typed тип nullable date, а в Added2Typed - просто date. И пойди догадайся. Причина в том, что Table.TransformColumnTypes всегда присваивает nullable type. Пытался сделать такую операцию:
Если все столбцы были типизированы через Table.TransformColumnTypes, замену не делало совсем, и Table.ColumnsOfType давало пустой список. Потом обнаружил, что замену делает только в тех столбцах, где тип был задан по примеру Added2Typed (через присвоение типа в процессе создания столбца, например, или через прописывание типа таблицы). Вот такая конструкция зато работает
Максим Зеленский написал: В Typed тип nullable date, а в Added2Typed - просто date
Да, соглашусь, года три-четыре тому назад Power Query трепетно относился к этому моменту. Потом похоже убрали, чтобы не раздражать пользователей. Но, вместо того, чтобы привести типизацию к единому виду, понаделали костылей.