Проекция / репликация в SQL-запросе?

Мой 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 в хранимой процедуре. Я надеялся, что есть способ сделать это без цикла.

ааа, я все еще не понимаю, что ты имеешь в виду под "проектом"

Shawn 15.10.2008 07:47

Был способ сделать это без циклов, но вы предпочли проигнорировать его. Почему?

Pittsburgh DBA 17.10.2008 02:46

Потому что это растопило бы мозги тех, кто с этим справлялся.

lesscode 18.11.2008 17:35
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
3
1 182
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Я не уверен, что вы сможете это сделать в вью. Вам придется использовать процедуру. Вы также можете сделать 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

Shawn 15.10.2008 08:01

Переменная table используется только в демонстрационных целях. С тем же успехом это может быть обычная таблица, и мы просто используем предложение WHERE.

Pittsburgh DBA 15.10.2008 08:13

ага, я не знаю, что такое перекрестное соединение 10 и 1

Shawn 15.10.2008 15:39

Я использовал такой вариант. Я думаю, что ваша переменная цикла должна быть @maxSlot, а не @i.

lesscode 16.10.2008 04:26

МЕСТНЫЙ: "Я не знаю?" Что это за критика? Просто потому, что вы никогда раньше не видели применяемой тактики, не сбивайте ее с толку. Ваш вопрос процедурный. Моя основана на съемках. Для некоторых это имеет значение, и на некоторых платформах это единственная возможность.

Pittsburgh DBA 17.10.2008 02:47

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

Shawn 17.10.2008 08:15

Ну вот. Это будет делать до 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

Другие вопросы по теме