代码之家  ›  专栏  ›  技术社区  ›  Kieran Benton

SQL Server跨行压缩

  •  1
  • Kieran Benton  · 技术社区  · 15 年前

    我必须以特定的顺序返回大约70000行的4列int,并且只能使用非常浅的缓存,因为涉及的数据非常不稳定,必须是最新的。数据的一个特性是,当数据按顺序排列时,它通常是高度重复的。

    为了减少网络带宽和客户端处理时间/资源,我已经开始研究各种减少行数的方法,但还没有在T-SQL中找到任何技术,在T-SQL中,我可以将表示行“压缩”为一行和一列。例如

    prop1    prop2    prop3    prop4
    --------------------------------
    0        0        1        53
    0        0        2        55
    1        1        1        8
    1        1        1        8
    1        1        1        8
    1        1        1        8
    0        0        2        55
    0        0        2        55
    0        0        1        53
    

    进入:

    prop1    prop2    prop3    prop4    count
    -----------------------------------------
    0        0        1        53       1
    0        0        2        55       1
    1        1        1        8        4
    0        0        2        55       2
    0        0        1        53       1
    

    我估计,如果可能的话,在许多情况下,一个70000行的结果集最多可以减少到几千。

    我是否在这里查找了错误的树(是否存在作为SQL Server协议一部分的隐式压缩)?

    有没有办法做到这一点(SQL Server 2005)?

    我不应该这样做有什么原因吗?

    谢谢。

    3 回复  |  直到 14 年前
        1
  •  1
  •   David Andres    15 年前

    这是可行的,尽管很难看到:

    ;WITH Ordering
    AS
    (
      SELECT Prop1,        
      Prop2,        
      Prop3,        
      Prop4,
      ROW_NUMBER() OVER (ORDER BY Y, X) RN
      FROM Props
    )
    SELECT 
      CurrentRow.Prop1, 
      CurrentRow.Prop2, 
      CurrentRow.Prop3, 
      CurrentRow.Prop4, 
      CurrentRow.RN - 
        ISNULL((SELECT TOP 1 RN FROM Ordering O3 WHERE RN < CurrentRow.RN AND (CurrentRow.Prop1 <> O3.Prop1 OR CurrentRow.Prop2 <> O3.Prop2 OR CurrentRow.Prop3 <> O3.Prop3 OR CurrentRow.Prop4 <> O3.Prop4) ORDER BY RN DESC), 0) Repetitions
    FROM Ordering CurrentRow
    LEFT JOIN Ordering O2 ON CurrentRow.RN + 1 = O2.RN
    WHERE O2.RN IS NULL OR (CurrentRow.Prop1 <> O2.Prop1 OR CurrentRow.Prop2 <> O2.Prop2 OR CurrentRow.Prop3 <> O2.Prop3 OR CurrentRow.Prop4 <> O2.Prop4) 
    ORDER BY CurrentRow.RN
    

    要点如下:

    1. 使用行数枚举每一行以获得正确的顺序。
    2. 仅当下一行有不同的字段或下一行不存在时,通过联接查找每个循环的最大值。
    3. 计算重复次数的方法是取当前行数(假定为该循环的最大行数)并从中减去上一个循环的最大行数(如果存在)。
        2
  •  2
  •   Eric    15 年前

    您可以使用 count 功能!这需要您使用 group by 条款,你说的地方 计数 如何分手,或 group 本身。 Gropu by 用于任何 aggregate function 在SQL中。

    select
        prop1,
        prop2,
        prop3,
        prop4,
        count(*) as count
    from
        tbl
    group by
        prop1,
        prop2,
        prop3,
        prop4,
        y,
        x
    order by y, x
    

    更新:上述操作由 y x ,不是结果集的一部分。在这种情况下,您仍然可以使用 Y X 作为其中的一部分 小组通过 .

    记住,如果没有排序列,那么顺序就没有意义,因此在本例中,我们必须尊重 Y X 小组通过 .

        3
  •  0
  •   Tim    14 年前

    在现代局域网上,70000行四列整数实际上并不担心带宽问题,除非您有许多工作站同时执行此查询;在带宽受限的广域网上,您可以使用不同的行来消除重复行,这一方法将节省带宽,但会消耗一些服务器CPU。但是,同样地,除非您有一个总是在峰值负载或接近峰值负载时运行的真正过载的服务器,否则额外的消耗将只是一个小插曲。70000行几乎没有。