Преобразовать таблицу частот обратно в не частотную таблицу (разгруппировать) - PullRequest
0 голосов
/ 02 октября 2019

В SQL Server у меня есть следующая таблица (фрагмент), которая является исходными данными, которые я получаю (я не могу получить необработанную таблицу, из которой она была сгенерирована).

  • Gradelevel |YoS |Инвентарь
  • 4 |0 |4000
  • 4 |1 |3500
  • 4 |2 |2000

В первой строке таблицы написано, что для 4-го класса насчитывается 4000 человек с 0-летним стажем работы (YoS).

Мне нужно найти медиану YoS для каждого уровня оценки. Это было бы легко, если бы мне не дали таблицу, агрегированную до уровня Gradelevel / YoS с суммой в столбце Inventory, но, к сожалению, мне не так повезло.

Мне нужно разгруппироватьсяэта таблица такая, что у меня есть новая таблица, в которой первая запись находится в таблице 4000 раз, следующая запись 3500 раз, следующие 2000 и т. д. (столбец инвентаризации не будет в этой новой таблице). Тогда я мог бы взять процент_диска () столбца YoS по уровню обучения и получить медиану. Затем я мог бы также использовать другие статистические функции в YoS для получения других сведений из данных.

До сих пор я рассматривал unpivot (кажется, не является кандидатом для моего варианта использования), CTE (можетя не нашел пример, близкий к тому, что я пытаюсь сделать), и функцию, которая перебирает таблицу выше, вставляя количество строк, указанное значением в инвентаре, в новую таблицу, которая становится моей «разгруппированной» таблицей, которую я могу запуститьстатистический анализ. Я считаю, что последний подход - лучший вариант, доступный для меня, но примеры, которые я все видел, повторяются и фокусируются на одном столбце таблицы. Мне нужно перебрать каждую строку, а затем использовать уровни ранга и значения yos, чтобы вставить количество [инвентаря] несколько раз, прежде чем переходить к следующей строке.

Кто-нибудь знает:

  1. Лучший способ сделать это иначе, чем метод итерации / курсора?
  2. Как выполнить итерацию по таблице для достижения моей цели? Я читал Есть ли способ перебрать табличную переменную в TSQL без использования курсора? , но мне трудно понять, как применить эту итерацию к моему сценарию использования.

Правка 10/3, вот код цикла, который я получил, который выдает то же самое, что и крест Джона. Pro - это любая статистическая функция, которая может быть запущена на нем, если она медленная.


    --this table will hold our row (non-frequency) based inventory data
    DROP TABLE IF EXISTS #tempinv
CREATE TABLE #tempinv(
amcosversionid INT NOT null,
pp NVARCHAR(3) NOT NULL,
gl INT NOT NULL,
yos INT NOT NULL

)

-- to transform the inventory frequency table to a row based inventory we need to iterate through it
DECLARE @MyCursor CURSOR,  @pp AS NVARCHAR(3), @gl AS INT, @yos AS INT, @inv AS int
BEGIN
    SET @MyCursor = CURSOR FOR
    SELECT payplan, gradelevel, step_yos, SUM(inventory) AS inventory 
   FROM  
  mytable
  GROUP BY payplan, gradelevel, step_yos     


    OPEN @MyCursor 
    FETCH NEXT FROM @MyCursor 

    INTO  @pp, @GL, @yos, @inv

    WHILE @@FETCH_STATUS = 0
    BEGIN
      DECLARE @i  int 
      SET @i = 1
      --insert into our new table for each number of people in inventory
      WHILE @i<=@inv
        BEGIN

            INSERT INTO #tempinv (pp,gl,yos) VALUES (@pp,@gl,@yos)
            SET @i = @i + 1
        END 
      FETCH NEXT FROM @MyCursor 
      INTO  @pp, @GL, @yos, @inv 
    END; 

1 Ответ

0 голосов
/ 02 октября 2019

Один из вариантов - использовать CROSS APPLY совместно со специальной таблицей. Это " расширит " ваши данные в N строк. Затем вы можете выполнить любой необходимый анализ.

Пример

Select * 
 From YourTable A
 Cross Apply (
              Select Top ([Inventory]) N=Row_Number() Over (Order By (Select NULL)) 
               From  master..spt_values n1, master..spt_values n2
             ) B 

Возвращает

Grd Yos Inven   N
4   0   4000    1
4   0   4000    2
4   0   4000    3
4   0   4000    4
4   0   4000    5
...
4   0   4000    3998
4   0   4000    3999
4   0   4000    4000
4   1   3500    1
4   1   3500    2
4   1   3500    3
4   1   3500    4
...
4   1   3500    3499
4   1   3500    3500
4   2   2000    1
4   2   2000    2
4   2   2000    3
...
4   2   2000    1999
4   2   2000    2000
...