2010-02-06 17 views
5

¿Alguien podría verificar mi declaración de SQL para un funcionamiento correcto y un enfoque general de sentido común?SQL Server-- tablas de unión y columnas SUM para cada fila distinta

Esto es lo que sucede: Tengo una tabla principal y secundaria con una relación de uno a varios, unida en una columna llamada AccountNumberKey. La tabla secundaria tiene columnas numéricas que necesito resumir.

La información es tal que todos los registros secundarios con un valor de AccountNumberKey dado siempre tendrán los mismos valores en sus dos columnas numéricas. Quiero unirme a estas tablas y para cada AccountNumberKey pone la suma de esas dos columnas en una tabla temporal. Solo necesito sumar las columnas de un solo registro secundario dado cada AccountNumberKey.

Algunos datos de la muestra por debajo de voluntad (espero) hacer esto más claro:

Parent Table Columns 


ParentID InstitutionID AccountNumberKey 

1  LocalHost   1873283 
2  Acme Brokers   3627389  
3  Dewey, Cheatem  1392876 
4  NCC1701    8837273 
5  Peyton Place   9981273 


Child Table Columns 


ChildID  AccountNumberKey Value1  Value2  ProposalNumber 
1    1873283   1000  100   58 
2    1873283   1000  100   59 
3    1873283   1000  100   60 
4    1873283   1000  100   61 

Aquí es mi SQL Declaración:

SELECT DISTINCT Parent.InstitutionID, AccountNumberKey, SUM(Child.Value1 + Child.Value2) as total 
     INTO #TempTable 
     FROM   Parent 
      INNER JOIN 
       Child ON Parent.AccountNumberKey = Child.AccountNumberKey 

     GROUP BY Parent.InstitutionID, Parent.AccountNumberKey, Child.ProposalNumber 

El objetivo es vincular las tablas y poner los datos en una tabla temporal por lo que se ve así:

TempTable columns 


InstitutionID  AccountNumberKey  Total 
LocalHost   1873283    1100 

¿Mi consulta SQL pasa a reunir? No soy un genio cuando se trata de agrupaciones y me pregunto si esto es A) correcto y B) un buen camino a seguir o si hay mejores combinaciones para intentar.

Gracias!

Respuesta

4

Esta consulta dará los resultados que parecen querer:

SELECT 
    P.InstitutionID, 
    P.AccountNumberKey, 
    Total = C.Value1 + C.Value2 
FROM 
    Parent P 
    INNER JOIN (
     SELECT DISTINCT AccountNumberKey, Value1, Value2 
     FROM Child 
    ) C ON P.AccountNumberKey = C.AccountNumberKey 

Pero quiero repetir lo que otros han dicho: si se puede hacer nada sobre el diseño, lo que debe, porque no se normaliza. Value1 y Value2 de su tabla Child realmente pertenecen a la tabla Parent, ya que son sobre Parent. ¿Qué ocurre si dos filas en la tabla Child tienen un conjunto de valores diferente para la misma AccountNumberKey? Sus datos serían incorrectos y ¿quién sabe qué tipo de consecuencias posiblemente desastrosas podrían tener para el negocio? El DISTINCT anterior fallará en este caso y devolverá dos filas para la fila principal.

ACTUALIZACIÓN:

larryq dijo:

En cuanto a valor1 y valor2 quizá necesidad de pertenecer a la tabla primaria, es posible que en el futuro van a ser diferentes para cada ProposalNumber/AccountNumberKey combinación.

En este caso, la consulta que le he dado daría resultados extraños. ¿Cómo va a decidir qué conjunto de valores usará para un número de cuenta? ¿Siempre querrás el número de propuesta más reciente? ¿Querrá ver una fila para cada conjunto distinto de Value1 y Value2? ¿Hay otra tabla para unirme para encontrar el número de propuesta actual a usar?

1

En primer lugar, si es verdadero que "los registros secundarios con un valor AccountNumberKey determinado siempre tendrán los mismos valores en sus dos columnas numéricas", entonces su esquema de tabla no está en la tercera forma normal (3NF). Debe haber otra tabla con una fila por AccountNumberKey, con AccountNumberKey como clave, y Value1 y Value2 como campos de datos y las consultas deben unirse a esta tabla (utilizando AccountNumberKey), para recuperar Value1 y Value2.

En segundo lugar, en esta situación, no debe unirse a una tabla secundaria a una tabla primaria en una columna de tabla primaria que es no una clave. Esto causará un producto cartesiano (donde la salida incluirá múltiples filas para cada fila en ambos lados de la unión, en efectivo doble o triple contando esos registros ...) ¿Es AccountNumberKey una clave para la tabla Parent?

Si no es así, la única columna en la tabla primaria que se debe utilizar como un FK en la tabla secundaria es la columna de clave ParentID.

Si es (si AccountNumberKey es único en la tabla de Padres), entonces las columnas Value1 y Value2 shhould estar en la tabla primaria, no en la tabla secundaria.

+0

Charles, puede unirse en cualquier columna que desee, independientemente del estado de la tecla. Aunque tal vez estabas diciendo que no es aconsejable? El servidor te permite unirte a todo lo que quieras. – ErikE

+0

@Emtucifor, Sí, tienes razón. Voy a editar para aclarar este punto ... unir resultados que no sean PK en productos cartesianos ... pero a veces (no aquí) eso es lo que quieres ... –

+0

@Charles, puedes une cualquier tabla a cualquier mesa de la manera que quieras y, en general, no voy más allá de 2NF sin una buena razón, rara vez vale la pena. –

1

Su unión no producirá los resultados, ya que no es única AccountNumberKey la unión produciría

LocalHost   1873283    1100 

4 veces de tiempo, uno para cada registro hijo, cuando se agrega que produciría 4400 como el valor.

+0

En realidad, eso no es cierto, ya que está agrupando por Child.ProposalNumber. Pero no obtendrá una fila por cada fila en la tabla padre. – ErikE

Cuestiones relacionadas