Как найти среднее из определенных записей T-SQL - PullRequest
0 голосов
/ 07 февраля 2011

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

DECLARE @TmpTbl_SKUs AS TABLE
(
    Vendor VARCHAR  (255),
    Number VARCHAR(4),
    SKU VARCHAR(20),
    PurchaseOrderDate DATETIME,
    LastReceivedDate DATETIME,
    DaysDifference INT
)

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

Можно ли получить среднюю разницу в днях SKU?Как я могу проверить, есть ли только 1 запись этого SKU?Мне нужны данные, если есть только 1 запись, то я должен найти ее на среднем уровне.

Вот структура:

У поставщика много номеров, а у номеров многоSKU

Любая помощь была бы отличной, я не могу ее найти, и я не могу найти что-либо связанное с этим в Интернете.Заранее спасибо.

Вот некоторые примеры данных:

Vendor       Number   SKU     PurchaseOrderDate              LastReceivedDate       DaysDifference

OTHER PMDD       1111         OP1111   2009-08-21 00:00:00.000    2009-09-02 00:00:00.000    12
OTHER PMDD        1111         OP1112   2009-12-09 00:00:00.000    2009-12-17 00:00:00.000    8
MANTOR             3333         MA1111   2006-02-15 00:00:00.000    2006-02-23 00:00:00.000    8
MANTOR             3333         MA1112   2006-02-15 00:00:00.000    2006-02-23 00:00:00.000    8

Извините, возможно, я написал это неправильно.Если для записи есть только 1 SKU, то я хочу вернуть DaysDifference (если оно не равно нулю), если в нем более 1 записи, и они не равны NULL, то вернуть среднюю разницу дней.Если это все нули, то на уровне продавца проверьте среднее значение skus, которые не равны нулю, в противном случае он должен просто вернуть 7. Вот что я пробовал:

SELECT t1.SKU, ISNULL
(
    AVG(t1.DaysDifference), 
    (
        SELECT ISNULL(AVG(t2.DaysDifference), 7)
        FROM @TmpTbl_SKUs t2
        WHERE t2.SKU=t1.SKU
        GROUP BY t2.ChampVendor, t2.VendorNumber, t2.SKU
    )
)
 FROM @TmpTbl_SKUs t1
 GROUP BY t1.SKU

Продолжайте играть с этим,Я в некоторой степени имею то, что получил, но просто не понимаю, как я могу проверить, есть ли у него несколько записей, и как проверить на уровне поставщика.

1 Ответ

0 голосов
/ 08 февраля 2011

Попробуйте:

РЕДАКТИРОВАНИЕ: добавлено NULLIF(..., 0) для обработки нулей как NULL.

SELECT
  t1.SKU,
  COALESCE(
    NULLIF(AVG(t1.DaysDifference), 0),
    NULLIF(t2.AvgDifferenceVendor, 0),
    7
  ) AS AvgDiff
FROM @TmpTbl_SKUs t1
  INNER JOIN (
    SELECT Vendor, AVG(DaysDifference) AS AvgDifferenceVendor
    FROM @TmpTbl_SKUs
    GROUP BY Vendor
  ) t2 ON t1.Vendor = t2.Vendor
GROUP BY t1.SKU, t2.AvgDifferenceVendor

РЕДАКТ. 2: как я тестировал скрипт.

Для тестирования я использую пример данных, размещенных с вопросом.

DECLARE @TmpTbl_SKUs AS TABLE
(
    Vendor VARCHAR  (255),
    Number VARCHAR(4),
    SKU VARCHAR(20),
    PurchaseOrderDate DATETIME,
    LastReceivedDate DATETIME,
    DaysDifference INT
)

INSERT INTO @TmpTbl_SKUs
      (Vendor,       Number, SKU,      PurchaseOrderDate,         LastReceivedDate,    DaysDifference)
SELECT 'OTHER PMDD', '1111', 'OP1111', '2009-08-21 00:00:00.000', '2009-09-02 00:00:00.000', 12
UNION ALL
SELECT 'OTHER PMDD', '1111', 'OP1112', '2009-12-09 00:00:00.000', '2009-12-17 00:00:00.000', 8
UNION ALL
SELECT 'MANTOR',     '3333', 'MA1111', '2006-02-15 00:00:00.000', '2006-02-23 00:00:00.000', 8
UNION ALL
SELECT 'MANTOR',     '3333', 'MA1112', '2006-02-15 00:00:00.000', '2006-02-23 00:00:00.000', 8;

Сначала я запускаю скрипт на неизмененных данных.Вот результат:

SKU                  AvgDiff
-------------------- -----------
MA1111               8
MA1112               8
OP1111               12
OP1112               8

AvgDiff для каждого SKU идентичен исходному DaysDifference для каждого SKU, потому что для каждого есть только одна строка.

Теперь яизменив DaysDifference для SKU='MA1111' на 0 и снова запустив скрипт.Результат:

SKU                  AvgDiff
-------------------- -----------
MA1111               4
MA1112               8
OP1111               12
OP1112               8

Теперь AvgDiff для MA1111 равен 4. Почему?Поскольку среднее значение для SKU равно 0, и поэтому берется среднее значение по поставщику, которое было вычислено как (0 + 8) / 2 = 4.

Следующим шагом является установка для DaysDifference значения 0 для всех SKU одного и того же поставщика.В этом случае я устанавливаю его для SKU MA1111 и MA1112.Вот результат сценария для этого изменения:

SKU                  AvgDiff
-------------------- -----------
MA1111               7
MA1112               7
OP1111               12
OP1112               8

Так что теперь AvgDiff равен 7 для MA1111 и MA1112.Как это стало так?Оба имеют DaysDifference = 0. Это означает, что среднее значение по поставщику должно быть принято для каждого.Но в среднем вендор тоже равен 0.В соответствии с требованием, среднее значение здесь должно по умолчанию равняться 7, что и было возвращено сценарием.

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

...