Показать сообщение отдельно
Старый 22.11.2007, 12:01   #18  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,656 / 1158 (42) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Не знаю, работает ли это в Oracle, но в MS SQL есть такая фича

PHP код:
SELECT InventSerialIdCOUNT(DISTINCT InventBatchId) AS Cnt    
FROM InventDim 
INNER JOIN InventTrans ON InventDim
.InventDimId InventTrans.InventDimId
WHERE InventSerialId 
<> CHR(2)  
GROUP BY InventSerialId
HAVING COUNT
(DISTINCT InventBatchId) <> 
COUNT(DISTINCT InventBatchId) - это количество уникальных значений указанного поля, а не вообще всех отобранных записей.

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

Кроме того, судя по коду, у Вас только одна компания, раз нет фильтра по DataAreaId.

Ну, а собственно JOB мне не нравится избыточным количеством проходов. Поскольку уже первый запрос упорядочивает данные по полям InventSerialId, InventBatchId, то какие проблемы тут же и подсчитать количество повторов? Ведь записи выстроены в нужной последовательности.

Собственно, все можно решить за один проход. И без каких-либо временных таблиц.

X++:
static void KKu_FindDupleInventSerialId(Args _args)
{
    InventDim       inventDim;
    InventTrans     inventTrans;
    int                  nextI;

    InventSerialId  inventSerialIdPrev;
    Container       conValue;

    ;

    info('Серийный номер --- Кол-во повторений -- Номер партии');
    info('====================================================');

    while
        select InventSerialId, InventBatchId from inventDim
        group by InventSerialId, InventBatchId
        exists join inventTrans
        where inventDim.InventDimId == inventTrans.InventDimId
    {
        if (inventDim.inventSerialId != inventSerialIdPrev)
        {
            if (inventSerialIdPrev && conLen(conValue) > 1)
            {
                for (nextI = 1; nextI <= conLen(conValue); nextI++ )
                {
                    info( strfmt('%1 --- %2 --- %3',
                        inventSerialIdPrev,
                        conLen(conValue), 
                        conPeek(conValue,nextI) ) );
                }
            }
            // Сброс значений очередной группы
            inventSerialIdPrev = inventDim.inventSerialId;
            conValue = conNull();
        }
        else
        {
            conValue += [inventDim.inventBatchId];
        }
        
    }

    if (inventSerialIdPrev && conLen(conValue) > 1)
    {
        for (nextI = 1; nextI <= conLen(conValue); nextI++ )
        {
            info( strfmt('%1 --- %2 --- %3',
                inventSerialIdPrev,
                conLen(conValue), 
                conPeek(conValue,nextI) ) );
        }
    }

}