В 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, чтобы вставить количество [инвентаря] несколько раз, прежде чем переходить к следующей строке.
Кто-нибудь знает:
- Лучший способ сделать это иначе, чем метод итерации / курсора?
- Как выполнить итерацию по таблице для достижения моей цели? Я читал Есть ли способ перебрать табличную переменную в 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;