2012-04-30 4 views
5

Tengo una tabla de SQL Server AccountAction que está denormalizada. Es una versión aplanada de las tablas Account y Action, que espero que sea mucho más rápido para informar consultas sobre millones de filas. Uno puede tener muchas AccountActions, por lo que la tabla es similar a:SQL para obtener X cantidad de cuentas de DB, que podría ser un número variable de filas

Account  Action 
account1 action1 
account1 action2 
account1 action10 
account2 action5 

Sin embargo estoy teniendo algunos problemas para conseguir la información de nuevo para un subconjunto restringido en un procedimiento almacenado simple.

select Account, Action 
from AccountAction 
where ??? 

Lo que estoy buscando es obtener las primeras X cuentas, con todas sus acciones. Entonces esta será una cantidad dinámica de filas. Entonces, usando la tabla de ejemplo anterior si pasé en 1, obtendría 3 filas (es decir, me daría todas las filas para la primera cuenta).

(no me importa que el nombre de la cuenta estará en cada fila - que pivota en otro lugar)

¿Es necesario utilizar un ROWNUM o similar a restringir las filas? Estoy seguro de que esto debe ser un problema más simple de lo que he encontrado hasta ahora.

EDITAR

Las respuestas usando TOP no va a funcionar, en el ejemplo que estaría queriendo 3 filas devueltas si dijera 'dame uno (el primero) cuenta'. ¿Pero cómo sé que habrá 3? Su dinámica Además, pueden no ser secuenciales, ¿y si action99 de la cuenta1 estuviera en la posición 55 millones en los resultados?

Respuesta

4
WITH 
    SequencedData 
AS 
(
    SELECT 
    DENSE_RANK() OVER (ORDER BY Account) AS account_sequence_id, 
    * 
    FROM 
    AccountAction 
) 
SELECT 
    * 
FROM 
    SequenceData 
WHERE 
    account_sequence_id = ??? 

O, por múltiplos ...

WHERE 
    account_sequence_id BETWEEN 3 AND 5 -- For the 3rd, 4th and 5th accounts. 
+0

Esto suena bien, aunque ¿qué pasa con el rendimiento en p. Ej. ¿100 m de hileras? Va a tener que hacer el rango en cada fila primero, ¿verdad? – finoutlook

+1

@finoutlook - Depende. Todo lo que * realmente * se necesita es tener los datos en orden 'Cuenta'. Una vez ordenado, el optimizador puede buscar la instancia 'Nth' de eso. Entonces, ¿ya tiene un índice con 'Cuenta' como primer campo? Si es así, los datos ya están ordenados y solo está procesando la cantidad mínima de registros. Si no, agregue uno;) – MatBailie

+0

Genial, no había pensado ordenarlos por adelantado. Podría hacer eso como parte de la sincronización con la tabla desnormalizada. – finoutlook

0

Si tengo la pregunta correcta entonces si quieres seleccionar inicial de 10 filas a continuación, utilizar

SELECT TOP 10 Account, Action 
FROM AccountAction 

o si quieres unos 20 registros iniciales por ciento luego uso-

SELECT TOP 10 PERCENT Account, Action 
FROM AccountAction 
+0

El PO quiere la cuenta 'Nth', donde cada cuenta puede tener un número diferente de registra cada uno – MatBailie

0

¿Has probado TOP?

declare @hoW_many int 
set @hoW_many = 10 

select top (@hoW_many) * 
from AccountAction 
+0

El OP no quiere las 'primeras N filas', el OP quiere la' Nth Cuenta', donde cada cuenta tiene un número diferente de filas. – MatBailie

1
SELECT * 
FROM AccountAction 
WHERE account IN (SELECT account 
    FROM AccountAction 
    GROUP BY account HAVING account BETWEEN *start-account* AND *end-account* 
    ORDER BY account 
) 

Explicación: Los grupos subconsulta por las cuentas distintas (y permite criterios de selección de grano más fino que un simple DISTINCT) y devuelve solamente esas cuentas. El SELECT externo le proporciona un número variable de filas dependiendo de las distintas cuentas que obtiene la subconsulta.

EDITAR: Lo anterior supone que se puede filtrar por el campo account en la tabla AccountAction; este suele ser el caso en las tablas que se unen a una relación M:N a nivel de base de datos.

+2

'LIMIT' no es una función del Servidor SQL. – GarethD

+0

@GarethD Gracias actualicé mi código para usar 'TOP' en su lugar, con el mismo efecto de' LIMIT' antes. –

+0

Cambio de publicación de LIMIT a TOP - ¿Qué pasa si el OP necesita el 3ro, 4to y 5to? Voy a +1 cuando hagas ese cambio también :) – MatBailie

0

Un simple sub-select con top palabra (y distinta), se le dará todas las acciones para el primer X representa

select * from AccountAction 
where Account in 
(select distinct top (@NumberOfAccounts) Account 
from AccountAction order by Account) 
+1

Necesita un ORDER BY en la subconsulta, de lo contrario los resultados pueden variar desde la ejecución hasta la ejecución. Entonces es lo mismo que la respuesta de JosvicZammit, de 6 minutos antes de la suya * (Donde DISTINCT y GROUP BY son intercambiables) *. – MatBailie

+0

@Dems - Respuesta modificada para incluir ORDER BY; pero mi intención no era incluir una respuesta duplicada ... –

Cuestiones relacionadas