Compression croisée de SQL Server

Je dois renvoyer ~ 70 000 lignes de 4 colonnes d'INT dans un ordre spécifique et ne peut utiliser qu'une caching très superficielle car datatables impliquées sont très volatiles et doivent être à jour. Une propriété des données est qu'elles sont souvent très répétitives quand elles sont en ordre.

J'ai commencé à examiner diverses methods de réduction du nombre de lignes afin de réduire la bande passante du réseau et les ressources / time de traitement côté client, mais je n'ai pas réussi à find de technique dans T-SQL où je peux «compresser» des lignes répétitives. vers le bas dans une seule rangée et une colonne de «count». par exemple

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 

Dans:

 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 

J'estime que si cela était possible, dans de nombreux cas, ce qui serait un set de résultats de 70 000 lignes serait au plus de quelques milliers.

Est-ce que j'aboie le mauvais tree ici (y a-t-il compression implicite dans le cadre du protocole SQL Server)?

Existe-t-il un moyen de faire cela (SQL Server 2005)?

Y a-t-il une raison pour laquelle je ne devrais pas faire ça?

Merci.

Cela fonctionnera, bien qu'il soit pénible de regarder:

 ;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 

L'essentiel est le suivant:

  1. Énumérer chaque ligne en utilisant ROW_NUMBER OVER pour get l'ordre correct.
  2. Trouvez les maximums par cycle en vous joignant seulement quand la rangée suivante a des champs différents ou quand la rangée suivante n'existe pas.
  3. Calculez le nombre de répétitions en prenant le numéro de ligne actuel (supposé être le maximum pour ce cycle) et en en soustrayant le numéro de ligne maximum du cycle précédent, s'il existe.

Vous pouvez utiliser la fonction de count ! Cela vous obligera à utiliser la clause group by , où vous dites count comment rompre, ou group , lui-même. Gropu by est utilisé pour toute fonction d'agrégat en SQL.

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

Mise à jour: Les PO mentionnés ci-dessus sont classés par y et x , et ne font pas partie du jeu de résultats. Dans ce cas, vous pouvez toujours utiliser y et x comme partie du group by .

Gardez à l'esprit que cet ordre ne signifie rien s'il n'a pas de colonnes de command, donc dans ce cas, nous devons respecter cela avec y et x dans le group by .

70 000 lignes de quatre colonnes entières ne sont pas vraiment un souci pour la bande passante sur un réseau local moderne, sauf si vous avez plusieurs stations de travail exécutant cette requête simultanément; et sur un WAN avec une bande passante plus restreinte, vous pouvez utiliser DISTINCT pour éliminer les lignes en double, une approche qui serait économe avec votre bande passante, mais consum un peu de CPU server. Encore une fois, cependant, à less que vous ayez un server vraiment surchargé qui fonctionne toujours à ou près des charges de pointe, cette consommation supplémentaire serait un simple point faible. 70 000 lignes sont à côté de rien.