SQL Server - объединить таблицы и столбцы SUM для каждой отдельной строки - PullRequest
4 голосов
/ 06 февраля 2010

Может ли кто-нибудь перепроверить мой оператор SQL на предмет правильной работы и общего подхода?

Вот что происходит: у меня есть родительская и дочерняя таблица с отношением один-ко-многим, соединенные в столбце AccountNumberKey. В дочерней таблице есть числовые столбцы, которые мне нужно подвести.

Данные таковы, что все дочерние записи с данным значением AccountNumberKey всегда будут иметь одинаковые значения в своих двух числовых столбцах. Я хочу присоединиться к этим столам и для каждый AccountNumberKey помещает сумму этих двух столбцов во временную таблицу. Мне нужно только суммировать столбцы из одной дочерней записи по каждому AccountNumberKey.

Некоторые примеры данных ниже (я надеюсь) прояснят ситуацию:

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

Вот мой SQL-оператор:

    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

Цель состоит в том, чтобы связать таблицы и поместить данные во временную таблицу так, чтобы она выглядела так:

TempTable columns


InstitutionID       AccountNumberKey        Total
LocalHost           1873283             1100

Мой запрос SQL проходит проверку? Я не гений, когда дело доходит до группировок, и мне интересно, правильно ли это A) и B) нормально ли это делать или есть ли лучшие объединения, которые можно попробовать.

Спасибо!

Ответы [ 3 ]

3 голосов
/ 06 февраля 2010

Этот запрос даст результаты, которые вам нужны:

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

Но я хочу повторить то, что сказали другие: если вы можете что-то сделать с дизайном, вы должны это сделать, потому что он не нормализован. Value1 и Value2 из вашей дочерней таблицы действительно принадлежат родительской таблице, так же как и родительской. Что если две строки в дочерней таблице имеют разные наборы значений для одного и того же AccountNumberKey? Ваши данные будут неверными, и кто знает, какие могут быть катастрофические последствия для бизнеса? Приведенный выше DISTINCT завершится с ошибкой и вернет две строки для родительской строки.

UPDATE:

Ларрик сказал:

Что касается value1 и value2, возможно, нуждающихся в принадлежности к родительской таблице, возможно, в будущем они будут различными для каждой комбинации ProposalNumber / AccountNumberKey.

В этом случае запрос, который я вам дал, даст странные результаты. Как вы решите, какой набор значений использовать для AccountNumber? Вы всегда будете хотеть самый последний ProposalNumber? Вы хотите увидеть строку для каждого отдельного набора значений Value1 и Value2? Есть ли еще одна таблица, к которой можно присоединиться, чтобы найти текущий номер ProposalNumber для использования?

1 голос
/ 06 февраля 2010

Ваше объединение не даст таких результатов, так как AccountNumberKey не является уникальным, объединение будет производить

LocalHost           1873283             1100

4 раза, по одному для каждой дочерней записи, при агрегировании это даст 4400 в качестве значения.

1 голос
/ 06 февраля 2010

Прежде всего, если это правда, что «дочерние записи с заданным значением AccountNumberKey всегда будут иметь одинаковые значения в своих двух числовых столбцах», тогда ваша схема таблицы не в надлежащей третьей нормальной форме (3NF). Должна быть другая таблица с одной строкой на AccountNumberKey, с AccountNumberKey в качестве ключа и Value1 и Value2 в качестве полей данных, и ваши запросы должны объединяться с этой таблицей (используя AccountNumberKey) для получения Value1 и Value2.

Во-вторых, в этой ситуации вам не следует присоединять дочернюю таблицу к родительской таблице в столбце родительской таблицы, который не является ключом . Это приведет к декартовому произведению (где выходной результат будет включать в себя несколько строк для каждой строки по обе стороны от объединения, в результате двойной или тройной подсчет этих записей ...) Является ли AccountNumberKey ключом для родительской таблицы?

Если это не так, то единственным столбцом в родительской таблице, который следует использовать в качестве FK в дочерней таблице, является ключевой столбец ParentID.

Если равно (если AccountNumberKey уникально в родительской таблице), то столбцы Value1 и Value2 должны находиться в родительской таблице, а не в дочерней таблице.

...