Нужна последняя запись при использовании XSUM в SYNCSORT JCL
У меня есть некоторые данные, как показано ниже:
Это не фактические данные, но фактические данные похожи на это. И данные поступают в файл с 2 пробелами между каждым полем. Ни одна база данных не участвует во вводе или выводе. Я использую формат таблицы, чтобы сделать ее понятной.
Name Number code
+---------------------+
Albert 122234 xcc
Robert 565435 rtd
Robert 776567 iuy
Robert 452890 yyt
Stuart 776565 ter
В файле данные будут выглядеть так...
Albert 122234 xcc
Robert 565435 rtd
Robert 776567 iuy
Robert 452890 yyt
Stuart 776565 ter
Теперь мне нужно устранить дубликаты с помощью SYNCSORT. Я могу сделать это с помощью XSUM, но я бы получил следующие данные:
Name Number code
+---------------------+
Albert 122234 xcc
Robert 565435 rtd
Stuart 776565 ter
Но мне нужно:
Name Number code
+----------------------+
Albert 122234 xcc
Robert 452890 yyt
Stuart 776565 ter
Последний набор данных имеет последнее вхождение Robert
на выходе, тогда как первый набор имеет первое вхождение.
Итак, есть ли способ добиться этого с помощью XSUM...?
3 ответа
Два шага, первый добавляет порядковый номер и сортирует по возрастанию имени и по убыванию порядкового номера. Это для того, чтобы получить последнюю запись для каждого имени, чтобы прийти первым.
Второй шаг сортируется только по имени с параметром EQUALS, который говорит, что данные должны храниться в той же последовательности, что и входной файл, в случае дублирования значений в полях SORT. Затем мы используем SUM FIELDS=NONE для устранения дубликатов.
//SORT1 EXEC PGM=SORT
//SORTIN DD *
ALBERT 122234 XCC
ROBERT 565435 RTD
ROBERT 776567 IUY
ROBERT 452890 YYT
STUART 776565 TER
//SYSIN DD *
INREC FIELDS=(001:001,020, * REGULAR INPUT DATA
021:SEQNUM,4,BI) * ADD A SEQUENCE NUMBER
SORT FIELDS=(001,008,CH,A,
021,004,BI,D)
OUTREC FIELDS=(001:001,020, * ORIGINAL INPUT DATA
080:C' ') * PADDING
//SORTOUT DD DISP=(NEW,PASS),
// AVGREC=U,
// LRECL=80,
// RECFM=FB,
// SPACE=(80,(1000,100))
//SYSOUT DD SYSOUT=*
//*
//SORT2 EXEC PGM=SORT
//SORTIN DD DISP=(SHR,PASS),DSN=*.SORT1.SORTOUT
//SYSIN DD *
SORT FIELDS=(001,008,CH,A),EQUALS
SUM FIELDS=NONE
//SORTOUT DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//*
Есть несколько способов сделать это.
Во-первых, с SyncTool (скорее всего, с псевдонимом ICETOOL, так что где-то по пути у вас EXEC PGM=ICETOOL). Посмотрите на оператор SELECT, который имеет LAST, который должен дать вам то, что вы хотите. Если ваш файл уже отсортирован, не сортируйте его снова (OPTION COPY в файле USING).
Пример можно найти в разделе "Хранить удаленные дубликаты записей (XSUM)" в этой публикации: ftp://ftp.software.ibm.com/storage/dfsort/mvs/sorttrck.pdf
В итоге вы получите контрольную карту по этим направлениям:
SELECT FROM(IN) TO(OUT) ON(1,3,CH) FIRST DISCARD(SORTXSUM)
Также простой пример здесь: http://www.ibmmainframes.com/viewtopic.php?p=310008
Если ваши данные уже отсортированы или после сортировки, используйте OUTFIL и "функции отчетности". Посмотрите на REMOVECC и NODETAIL, используйте РАЗДЕЛЫ и ТРЕЙЛЕР3. Вот пример http://www.ibmmainframes.com/viewtopic.php?p=309955.
В итоге вы получите контрольные карты по этим направлениям:
OPTION EQUALS
SORT FIELDS=(1,3,CH,A)
OUTFIL REMOVECC,NODETAIL,SECTIONS=(1,3,TRAILER3=(1,80))
Если вы сортируете данные и хотите использовать XSUM, чтобы сохранить разрозненные дубликаты в отдельном наборе данных, вы можете включить порядковый номер во временное добавление к записи и SORT для этого, По убыванию, после основного ключа. Отбросьте временное расширение. Это невозможно сделать за один шаг, но SELECT (конечно, версия DFSORT) может делать все, что делает XSUM и даже больше, в одной функции.
Наконец, после того, как что-то ворчало у меня в голове, если у вас текущий SyncSort по крайней мере 1,4, вы можете делать именно то, что вы хотите (при условии, что мы до сих пор не знаем, что это такое) с DUPKEYS с LASTDUP и XDUP вместо SUM и XSUM.
В итоге вы получите контрольную карту по этим направлениям:
DUPKEYS LASTDUP,NODUPS,XDUP
Похоже, вы хотите сохранить последнюю запись набора записей, имеющих одинаковый ключ сортировки.
Если у вас есть недавняя версия SyncSort, используйте DUPKEYS с LASTDUP и EQUALS, как указано в других ответах.
Прошло много времени с тех пор, как я использовал SyncSort, но если я правильно помню, можно закодировать процедуру выхода, которая имеет доступ к ключам сортировки и может принимать или отклонять записи. Процедура выхода вводится для каждой записи, поэтому можно сохранить предыдущие ключи сортировки для сравнения.
Кроме того, мне нравится писать выходы в ассемблере (BAL), но это можно сделать с помощью кода COBOL.
Итак, если SyncSort поддерживает команду, которая делает то, что вы хотите, то непременно используйте ее! Если нет, то выходы относительно легко закодировать...