【问题标题】:Disaggregate Table Over 2 Columns in T-SQL在 T-SQL 中将表分解为 2 列
【发布时间】:2012-02-16 19:30:02
【问题描述】:

如果我有下表

Hour    Clicks  Conversions
12:00   2   0
1:00    3   2
2:00    1   1

我如何编写一个 SELECT 语句来分解它在两列中,所以我得到:

12:00   1   0
12:00   1   0
1:00    1   0
1:00    1   1
1:00    1   1
2:00    1   1

如果我不能使用 SELECT 执行此操作,我如何编写一个使用循环执行此操作的存储过程?

谢谢!

【问题讨论】:

  • +1 有趣的问题。不是一个新的,但我花了几分钟才想到解决方案,所以你得到了我的支持。 :-)
  • 我没有看到似乎总是返回 1 的第二列的点

标签: sql-server-2008 tsql stored-procedures


【解决方案1】:

这假设对于任何给定的 [Hour] 值都只会有一行。如果可能有重复,我会先聚合那些(我假设源已经是某种聚合)。

DECLARE @x TABLE ([Hour] CHAR(5), Clicks INT, Conversions INT);

INSERT @x SELECT '12:00',2,0
UNION ALL SELECT '13:00',3,2
UNION ALL SELECT '14:00',1,1;

;WITH x AS
(
    SELECT n = ROW_NUMBER() OVER (ORDER BY s1.[object_id]) FROM sys.all_columns AS s1
    -- CROSS JOIN (SELECT 1 UNION ALL SELECT 2) AS s2 -- to double the rows if you need more
),
y AS 
(
    SELECT [Hour], Conversions, Clicks, 
    m = MAX(CASE WHEN Conversions > Clicks THEN Conversions ELSE Clicks END) 
    FROM @x GROUP BY [Hour], Conversions, Clicks
)
SELECT y.[Hour],
    Clicks = CASE WHEN Clicks < x.n THEN 0 ELSE 1 END,
    Conversions = CASE WHEN Conversions < x.n THEN 0 ELSE 1 END
FROM x INNER JOIN y ON x.n <= y.m
ORDER BY CONVERT(TIME, y.[Hour]), Clicks, Conversions;

【讨论】:

    【解决方案2】:

    这不是最有效的方法,但可能足以让您入门。

    DECLARE @T TABLE (
        Hour            TIME
        , Clicks        INT
        , Conversions   INT
    );
    
    INSERT @T VALUES ( '12:00', 2, 0 );
    INSERT @T VALUES ( '1:00', 3, 2 );
    INSERT @T VALUES ( '2:00', 1, 1 );
    
    
    DECLARE @Stage TABLE (
        Hour            TIME
        , Clicks        INT
        , Conversions   INT
    );
    
    DECLARE @MaxClicks INT;
    
    SELECT @MaxClicks = MAX(Clicks) FROM @T;
    
    DECLARE @ClickCount INT; SET @ClickCount = 1;
    
    WHILE @ClickCount <= @MaxClicks
    BEGIN
        INSERT @Stage ( Hour, Clicks, Conversions )
        SELECT Hour, 1, CASE WHEN Conversions >= @ClickCount THEN 1 ELSE 0 END
        FROM @T WHERE Clicks >= @ClickCount;
    
        SET @ClickCount = @ClickCount + 1;
    END;
    
    SELECT * FROM @Stage ORDER BY Hour;
    

    【讨论】:

    • 虽然不太可能(我只知道这一点是因为我熟悉数据模型的类型),但如果在给定小时内转化次数高于点击次数怎么办?例如可能有人在 3:59 点击并在 4:01 购买。
    • 要点...我想您的计数表方法也会更有效。
    • 我想是的。但请称其为数字表。它没有计算任何东西。 :-)
    【解决方案3】:
    DECLARE @x TABLE ([Hour] TIME, Clicks INT, Conversions INT);  
    INSERT @x VALUES ('12:00',2,0),('13:00',3,2), ('14:00',1,1); 
    
    ;WITH a as
    (
    SELECT [hour], 1 [unnessasary column], clicks, CASE WHEN clicks <= Conversions THEN 1 ELSE 0 END click, Conversions
    FROM @x
    UNION ALL
    SELECT [hour], 1, clicks-1,CASE WHEN clicks-1 <= Conversions THEN 1 ELSE 0 END, Conversions
    FROM a
    WHERE clicks > 1
    )
    SELECT [hour],[unnessasary column], click
    FROM a
    ORDER BY 1
    OPTION (maxrecursion 0)
    

    【讨论】:

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