Machetes Varios

apuntes varios erp cwa logic ( ahora SoftLand Logic ) – sql y veremos que otra cosa

T-SQL Tiebreakers


Sql Magazine ID45235

By: Itzik Ben-Gan

El código aqui ( renombrar a .zip)

Artículo relacionado: agregating-and-pivoting-data.pdf

El Tiebreaker en T-SQL es una regla que determina que registro debe devolver la consulta, si hay varios con los mismos valores en una serie de atributos..

Ejemplo ( base de datos NorthWind): Se desea traer la orden más reciente de cada empleado. atributos:EmployeeID, OrderID, CustomerID, ShipVia, OrderDate
Tabla: Orders

Si se deseara traer solamente OrderDate no habría problema — Se resueve simplemente con un GROUP BY y un MAX. El tema está en que se desean traer todos esos atributos y un empleado puede tener más de una orden para el mismo día(OrderDate). Entonces, se necesita un tiebreaker: una regla adicional que identifique un único registro por empleado, por ejemplo, se agrega la MAX(OrderID).

Ver como el código del listado2 trae dos registros para el empleado 2

Se proponen cuatro soluciones.

1) Con SubConsultas ANSI

La Consulta en el Listado3. El índice recomendado se formade la siguiente manera: correlation column,sort columns,tiebreaker column,covered column. O sea: EmployeeID,OrderDate,OrderID,CustomerID,ShipVia.

La consulta funciona bien( si se crea el índice) y la complejidad es baja. Pero, al ir agregando Tiebreakers la performance cae y aumenta la complejidad . Observar el listado4 donde se especifican 3 tiebreakers.

2) Usando TOP 1

Ver el listado5. En la subquerie se ordena por :correlation column,sort columns,tiebreaker column.

La consulta corre bien y se nota más en cuanto a performance y complejidad cuando se agregan tiebreakers, ya que solamente se van agregando campos al ORDER BY.

3) Usando TOP 1 y JOIN

Ver listado6

Si el número de empleado es chico, se puede mejorar el punto 2), consultando la tabla de Empleados ( en vez de la de Órdenes):

SELECT TOP 1 OrderID
FROM Orders AS K
WHERE K.EmployeeID = E.EmployeeID
ORDER BY OrderDate DESC, OrderID DESC) AS topkey
FROM Employees AS E

4) Usando Concatenación

Observar listado7

Las soluciones anteriores funcionan bien si existen los índices adecuados. Si dichos índices no existieran y no hay posibilidad de agregarlos, se presenta una nueva solución.

La idea es concatenar en forma de una columna binary:

correlation column,sort columns,tiebreaker column,covered column

y obtener el máximo de dicha columna. Luego, en la consulta externa extraer el valor de cada atributo de dicha columna ( Ver que la función SUBSTRING cuenta cantidad de bytes cuando se aplica sobre campos binary).

O sea:

Select EmployeeID, Extracción(stringbinario)

FROM

( SELECT EmployeeID, MAX(stringbinario)

FROM ORDERS

GROUP BY EmployeeID ) as D

La principal ventaja de la solución es la performance. La desventaja es que es compleja y no intuitiva o trivial. Segundo, solamente se puede utilizar si los tipos de datos de las sortcolumns y tiebreakers mantienen su comportamiento cuando se las convierte a otro tipo ( binary ) a los efectos de la concatenación. Finalmente , todas las otras soluciones permiten controlar separadamente la direccipon del sort por cada atributo, en tanto aquí no , salvo con los campos numéricos. Por ejemplo para cambiar la dirección a OrderID, hay que concatenar MAXINT-OrderID >>> 2147483647-OrderID. Al Extraer, se extrae: 2147483647-OrderID.

noviembre 15, 2006 - Posted by | sql magazine, Transact SQL

1 comentario »

  1. […] MAXITM2: Es el item correspondiente a los conceptos Base, con el máximo IMPNAC. Uso éste para “cocinar” la diferencia, ya que es donde el cambio será menos representativo. Observar que se usa la técnica de Tiebreakers […]

    Pingback por Desglose Impositivo « Machetes Varios | diciembre 7, 2006 | Responder


Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: