Мой SQL немного ржавый - есть ли способ SQL спроецировать входную таблицу, которая выглядит примерно так:
Name SlotValue Slots
---- --------- -----
ABC 3 1
ABC 4 2
ABC 6 5
В «прогнозируемую» таблицу результатов, которая выглядит следующим образом:
Name SlotSum Slot
---- ------- ----
ABC 13 1
ABC 10 2
ABC 6 3
ABC 6 4
ABC 6 5
Другими словами, результирующий набор должен содержать количество строк, равное MAX (слоты), перечисленных (слот) от 1 до MAX (слоты), а сумма для каждого из этих «слотов» должна отражать сумму спроектированных значений SlotValues. в положение «Слоты». для патологического случая:
Name SlotValue Slots
---- --------- -----
ABC 4 3
мы должны получить:
Name SlotSum Slot
---- ------- ----
ABC 4 1
ABC 4 2
ABC 4 3
Логика суммирования довольно проста - спроецируйте каждое SlotValue на количество слотов:
SlotValue SlotValue SlotValue Slot Sum
--------- --------- --------- ---- ---
3 4 6 1 13 (3+4+6)
0 4 6 2 10 (0+4+6)
0 0 6 3 6 (0+0+6)
0 0 6 4 6 (0+0+6)
0 0 6 5 6 (0+0+6)
ОБНОВЛЕНИЕ: В конце концов, я использовал вариант подхода LOCALGHOST в хранимой процедуре. Я надеялся, что есть способ сделать это без цикла.
Был способ сделать это без циклов, но вы предпочли проигнорировать его. Почему?
Потому что это растопило бы мозги тех, кто с этим справлялся.


Я не уверен, что вы сможете это сделать в вью. Вам придется использовать процедуру. Вы также можете сделать ProjectedTable таблицей временных / переменных в процедуре. Мне было бы действительно интересно посмотреть, как вы это поместите в представление, потому что вам нужно динамически генерировать диапазон чисел.
declare @maxSlot int
set @maxSlot = select max(slots) from SlotTable
truncate ProjectedTable
while @i > 0
begin
insert into ProjectedTable (
SlotSum
,Slot
) values (
(select sum(slotValue) from SlotTable where slots >= @maxSlot)
,@maxSlot
)
set @maxSlot = @maxSlot - 1
end
select SlotSum, Slot from ProjectedTable
меня голосуют против, но я не понимаю, почему, пока кто-то другой не сделает это без переменных ...; p
Переменная table используется только в демонстрационных целях. С тем же успехом это может быть обычная таблица, и мы просто используем предложение WHERE.
ага, я не знаю, что такое перекрестное соединение 10 и 1
Я использовал такой вариант. Я думаю, что ваша переменная цикла должна быть @maxSlot, а не @i.
МЕСТНЫЙ: "Я не знаю?" Что это за критика? Просто потому, что вы никогда раньше не видели применяемой тактики, не сбивайте ее с толку. Ваш вопрос процедурный. Моя основана на съемках. Для некоторых это имеет значение, и на некоторых платформах это единственная возможность.
я не знаю, потому что основная причина, по которой люди будут возражать против использования процедурного, заключается в том, что он намного медленнее и не масштабируется. конечно, вы тоже не можете использовать представление. однако ваш метод вообще не масштабируется
Ну вот. Это будет делать до 100 слотов в его нынешнем виде. Вы можете использовать свое воображение, чтобы приспособиться к большему.
DECLARE @SLOT TABLE
(
SlotName varchar(25) NOT NULL,
SlotValue int NOT NULL,
Slot int NOT NULL
)
INSERT INTO @SLOT (SlotName, SlotValue, Slot)
SELECT 'ABC', 3, 1
UNION
SELECT 'ABC', 4, 2
UNION
SELECT 'ABC', 6, 5
SELECT
CASE
WHEN SLOT.SlotName IS NOT NULL THEN SLOT.SlotName
ELSE
COALESCE(
(SELECT TOP 1 SL.SlotName FROM @SLOT AS SL WHERE SL.Slot < SLOT_PROJECT.Slot ORDER BY SL.Slot DESC),
(SELECT TOP 1 SL.SlotName FROM @SLOT AS SL WHERE SL.Slot > SLOT_PROJECT.Slot ORDER BY SL.Slot ASC)
)
END AS SlotName,
(
SELECT
SUM(SLOT10.SlotValue)
FROM
@SLOT AS SLOT10
WHERE
SLOT10.Slot >= SLOT_PROJECT.Slot
) AS SlotSum,
SLOT_PROJECT.Slot
FROM
(
SELECT
(TENS.Seq + ONES.Seq) AS Slot
FROM
(
SELECT 1 AS Seq
UNION ALL
SELECT 2
UNION ALL
SELECT 3
UNION ALL
SELECT 4
UNION ALL
SELECT 5
UNION ALL
SELECT 6
UNION ALL
SELECT 7
UNION ALL
SELECT 8
UNION ALL
SELECT 9
) AS ONES
CROSS JOIN
(
SELECT 0 AS Seq
UNION ALL
SELECT 10
UNION ALL
SELECT 20
UNION ALL
SELECT 30
UNION ALL
SELECT 40
UNION ALL
SELECT 50
UNION ALL
SELECT 60
UNION ALL
SELECT 70
UNION ALL
SELECT 80
UNION ALL
SELECT 90
) AS TENS
WHERE
(TENS.Seq + ONES.Seq) <= (SELECT MAX(Slot) FROM @SLOT)
) AS SLOT_PROJECT
LEFT JOIN @SLOT AS SLOT ON
SLOT.Slot = SLOT_PROJECT.Slot
ааа, я все еще не понимаю, что ты имеешь в виду под "проектом"