【问题标题】:Projection/Replication in SQL Query?SQL 查询中的投影/复制?
【发布时间】:2008-10-15 03:06:19
【问题描述】:

我的 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(Slots) 的行数,从 1 到 MAX(Slots) 的枚举 (Slot),并且每个“slots”的总和应该反映SlotValues 投影到“插槽”位置。对于病理情况:

Name               SlotValue                Slots
----               ---------                -----
ABC                4                        3

我们应该得到:

Name               SlotSum                  Slot
----               -------                  ----
ABC                4                        1
ABC                4                        2
ABC                4                        3

求和逻辑非常简单——将每个 SlotValue 投影到 Slot 的数量:

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 方法的变体。我希望有一种方法可以在没有循环的情况下做到这一点。

【问题讨论】:

  • 啊我还是不明白,你说的“项目”是什么意思
  • 有一种方法可以不使用循环,但您选择忽略它。为什么?
  • 因为它会融化必须处理它的维护人员的大脑。

标签: sql tsql


【解决方案1】:

我不确定您能否在视图中执行此操作。你必须使用一个程序。 您也可以在过程中使 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
  • 表变量仅用于演示目的。也可以是一张普通的表,我们只使用 WHERE 子句。
  • 嗯,我不知道交叉连接 10 和 1 的事情
  • 我使用了这个的变体。我认为您的循环变量需要是 @maxSlot 而不是 @i。
  • 本地幽灵:“我不知道?”这是怎样的批评?仅仅因为您以前从未见过使用过的策略,所以不要敲它。你的是程序性的。我的是基于集合的。这对某些人很重要,在某些平台上,这是唯一的机会。
【解决方案2】:

给你。这将以其当前形式执行多达 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多