Cache': техника группировки

То есть из четырех исходных получили две выходные, причем в выходных строках в одну ячейку попали от одного до нескольких

Cache: техника группировки

Информация

Компьютеры, программирование

Другие материалы по предмету

Компьютеры, программирование

Сдать работу со 100% гаранией
еляется выбранным символом - разделителем. Если он меньше пробела, то результат будет отсортирован. И, так же как в первом случае, следует дополнять индексное значение неким символом на случай получения группировки только по одному полю и при возможности получения в качестве значения поля пустой строки.

В случае использования групировки, ориентированной на функцию $ORDER, результат, конечно, будет неким образом отсортирован, но результат врядли будет удовлетворительным, поскольку будет применяться индексная сортировка к агрегату полей, что является строковой сортировкой. В случае использования нестроковых (числовых) значений полей следует приводить их значения к строкам таким образом, чтобы сортировка проводилась в правильном порядке, соответствующем типу данных. Например, в случае использования целых чисел их следует заменять примерно как: число 123 заменяем на строку "+00000123". То есть во-первых добавляем символ знака, во-вторых дополняем нулями до некоторой выбранной длины. В случае использования дробных чисел ситуация усложняется - следует в строку вносить символ знака числа, десятичный символ, дробную часть, знак и величину порядка. Причем расположить эти части следует в порядке, обеспечивающем именно строковую сортировку. После проведения группировки с такой сортировкой в функции визуализации также следует провести соответствующую коррекцию данных, чтобы убрать нагромождение дополняющих нулей.

Впрочем, в ситуации с особой трудоемкостью дополнений полей с целью совмещения группировки с сортировкой ничто не мешает выполнить сортировку в виде операции, отдельной от группирования. Об этом тоже не следует забывать - сортировка как отдельная операция может понадобиться в ситуации, когда следует выполнить сортировку по негруппирующим полям.

Рассмотрим другое деление группировки - на нормальную и широкую. Проблемой, породившей такое деление, является ограниченность длины индекса. В нашем случае это существенно, поскольку в индексные значения пишутся значения полей. Каким бы ни было магическое число этого ограничения, в целях эффективности реализации СУБД в каждой реализации оно есть. В отдельных реализациях размер индекса совпадает с величиной группировки, в других это две разные величины, но в любом случае предполагаются ограничения на максимальную величину индекса и группирующих полей. Вообще говоря, в большинстве случаев несложного применения и несложного анализа двух вышеприведенных способов группирования вполне хватает. Поэтому оба они называются нормальной группировкой, поскольку в обоих случаях слева от символа равенства стоят именно значения группирующих полей.

Но если все хорошо работает, то программисты этим, как правило, не занимаются, и нас более интересует случай, когда не работает. Или, в случае с группировкой, стоит вопрос - как провести группирование в ситуации, когда величина группирующих полей не уместилась в ограничение индекса.

В этой ситуации помогает условная замена значений полей на соответствующие этим значениям числовые идентификаторы. Скажем, цвету красный сопоставляется число 1, цвету синий - 2 и так далее, после чего в группировании принимают участие не длинные поля типа названия организации, а короткие числа.

Эти промежуточные идентификаторы значений должны быть числами, для которых можно задать, во-первых, взаимно однозначное соответствие между значением и числом и, во-вторых, на наборе чисел должен быть определен порядок, соответствующий порядку значений полей. Выполняем два прохода. В первом получаем список значений группирующих полей, попавших в выборку, во втором проводим собственно группировку. При выдаче результата используем отображение числовых значений на значения полей. Примерный код получения списка значений:

WideGroup()

k group,map

n i,color,figure,count

s i=""

f s i=$O(^group(i)) q:i="" d

. s color=$p(^group(i),"~",1)

. s figure=$p(^group(i),"~",2)

. ; save colors and figures into special lists

. s map("color",color)=""

. s map("figure",figure)=""

После этого в локальной переменной map содержатся два списка с цветами и фигурами. Отметим, что до полного прохода по результатам выборки данных, попавших на группировку (в нашем случае это O(^group(i))) мы просто не можем построить сортированного списка числовых идентификаторов значений, поскольку данные приходят в заведомо несортированном виде.

После получения списков значений группирующих полей можем построить отображение на соответствующие числовые значения:

s color=""

f s color=$O(map("color",color)) q:color="" d

. ; map color to ordered number

. s map("color",color)=$I(map("color"))

. ; map ordered number to color

. s map("Ncolor",map("color",color))=color

 

s figure=""

f s figure=$O(map("figure",figure)) q:figure="" d

. ; map figure to ordered number

. s map("figure",figure)=$I(map("figure"))

. ; map ordered number to figure

. s map("Nfigure",map("figure",figure))=figure

После этого в локальной переменной map имеем отображение значений цветов и фигур на числа, причем числа благодаря использованию индексной сортировки в O(map("color",color)) и O(map("figure",figure)) упорядочены в том же порядке. После этого, используя отображения значений на числа, можем провести широкую группировку:

n ncolor,nfigure

s i=""

f s i=$O(^group(i)) q:i="" d

. s color=$p(^group(i),"~",1)

. s figure=$p(^group(i),"~",2)

. s ncolor=map("color",color)

. s nfigure=map("figure",figure)

. s count=$p(^group(i),"~",3)

. s group(ncolor,nfigure)=count+$G(group(ncolor,nfigure),0)

q

Объединив образцы кода вместе, получим функцию, которая выполняет широкую группировку. Отметим, что никакой оптимизации здесь не приводилось, а получение данных, попадающих на группирование, не всегла такая простая операция, как просто проход по глобали. И, чтобы не выполнять ее дважды, имеет смысл в реальном коде сохранить выборку во временной глобали. И использовать глобали для группирования и отображения группирующих значений на числа. Поскольку данных может оказаться столь много, что они просто не поместятся в области данных процесса.

При выводе сгруппированных данных следует, конечно же, помнить, что группировали мы не значения, а их номера, поэтому используем построенное ранее отображение:

WriteWideGrouped()

d WideGroup()

n color,ncolor,figure,nfigure,count,cf

s cf="group"

f s cf=$Q(@cf) q:cf="" d

. s ncolor=$qs(cf,1)

. s nfigure=$qs(cf,2)

. s count=@cf

. s color=map("Ncolor",ncolor)

. s figure=map("Nfigure",nfigure)

. w color,?15,figure,?30,count,!

q

Сложно говорить о группировке и не затронуть группировку с подытогами. Например, получение той же группировки, но в которую вставлены данные отдельно по цветам безотносительно фигур игрушек, а также общая величина. Ничего сложного в этом нет. Конечно же, следует использовать тот же механизм группирования, но для каждой строки писать суммирование не только со строкой, идентифицируемой группой полей, но и идентифицируемой специальным маркером подитога вместо группирующего поля. Например, выбрав в качестве маркера подитога символ $C(11), получим группирование с подытогами по цвету:

; group to use $QUERY function

; use SUM function

k group

n i,color,figure,count

s i=""

f s i=$o(^group(i)) q:i="" d

. s color=$p(^group(i),"~",1)

. s figure=$p(^group(i),"~",2)

. s count=$p(^group(i),"~",3)

. s group(color,figure)=count+$G(group(color,figure),0)

. s group(color,$C(11))=count+$G(group(color,$C(11)),0)

q

Получение группировки с подытогами на самом деле не такая простая операция. Не буду приводить полностью код, являющийся правильным, отмечу лишь, что следует внимательно отнестись к дополнениям полей, чтобы подытоги сортировались правильным образом. И при выдаче результата в зависимости от использованной технологии визуализации давали разумное расположение подытогов.

Список литературы

Для подготовки данной работы были использованы материалы с сайта http://karataev.nm.ru/

 

 

Похожие работы

< 1 2