СУММА SQL на нескольких ВНУТРЕННИХ - PullRequest
0 голосов
/ 29 августа 2018

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

У меня есть состояние таблицы как

| STATE |   MONTH | ID | TOTAL |
--------------------------------
|    FL |    July |  1 | 10000 |
|    CA |   April | 32 |  2000 |

У меня есть другой стол Баланс как

| STATE |  Balance|
-------------------
|    FL |      100|
|    FL |      200|
|    CA |      300|
|    CA |      200|
|    CA |      100|

У меня есть еще одна таблица Loan как

| STATE |     Loan|
-------------------
|    FL |      500|
|    FL |      600|
|    CA |      700|
|    CA |      100|
|    CA |      200|

В результате моего запроса я хочу получить

| STATE |     Loan| Balance|
----------------------------
|    FL |     1100|     300|
|    CA |     1000|     600|

Когда я пытаюсь использовать следующий запрос, я правильно получаю сумму для кредита с состоянием,

SELECT 
  S.STATE, 
  SUM(L.Loan) 
FROM State AS S
  INNER JOIN Loan AS L ON L.STATE = S.STATE
GROUP BY
 S.STATE

Я получаю следующий результат,

| STATE |      Loan|
--------------------
|    FL |      1100|
|    CA |      1000|

Точно так же я могу получить сумму из таблицы баланса. То, что я пытаюсь достичь, это получить сумму из обеих таблиц, используя одну транзакцию.

Хотя я могу получить нужные значения, если я сделаю что-то подобное,

SELECT
  STATE AS STATE
  SUM(DataSetB.Balance) AS Balance
FROM
    (
    SELECT 
      STATE AS STATE,
      B.Balance AS Balance
    FROM
        (
        SELECT 
          S.STATE AS STATE, 
          SUM(L.Loan) AS Loan,
        FROM State AS S
          INNER JOIN Loan AS L ON L.STATE = S.STATE
        GROUP BY S.STATE
        )
        AS DataSetL
     INNER JOIN Balance AS B ON B.STATE = DataSetL.STATE
     GROUP BY
       DataSetL.STATE, B.Balance
     ) AS DataSetB
GROUP BY 
  DataSetB.STATE

Однако это не очень возможно для большого набора данных, который у меня есть. Я пытался,

SELECT 
  S.STATE AS STATE, 
  SUM(L.Loan) AS Loan,
  SUM(B.Balance) AS Balance
FROM State AS S
  INNER JOIN Loan AS L ON L.STATE = S.STATE
  INNER JOIN Balance AS B ON B.STATE = S.STATE
GROUP BY 
  S.STATE

Но это дает мне значения, кратные фактическому значению. Фактически это кратное число строк в дочерних таблицах.

Я не прошу точного решения, но любые указатели были бы хороши.

Ответы [ 8 ]

0 голосов
/ 29 августа 2018

Вы также можете использовать APPLY:

SELECT s.*, l.loan, b.balance 
FROM State s OUTER APPLY
     (SELECT SUM(l.loan) loan
      FROM loan l
      WHERE l.state = s.state
     ) l OUTER APPLY 
     (SELECT SUM(b.balance) balance 
      FROM balance b
      WHERE b.state = s.state
     ) b;
0 голосов
/ 29 августа 2018

Я бы порекомендовал использовать общее табличное выражение, так как оно довольно «чистое» для чтения.

Попробуйте что-то вроде следующего:

WITH CTE_TotalLoan AS (
  SELECT
    State,
    SUM(Loan) AS TotalLoan
  FROM Loan
  GROUP BY State
),

CTE_TotalBalance AS (
  SELECT
    State,
    SUM(Balance) AS TotalBalance
  FROM Balance
  GROUP BY State
)

SELECT 
  S.State,
  TotalLoan,
  TotalBalance
FROM State AS S
INNER JOIN CTE_TotalLoan AS L ON L.STATE = S.STATE
INNER JOIN CTE_TotalBalance AS B ON B.STATE = S.STATE

См. рабочий SQL Fiddle .

0 голосов
/ 29 августа 2018

попробуйте это:

        Create Table #Loan([State] Varchar(10),Loan Bigint)
        Create Table #Balance([State] Varchar(10),Balance Bigint)

        Insert Into #Loan
        Select 'FL',500 Union All
        Select 'FL',600 Union All
        Select 'CA',700 Union All
        Select 'CA',100 Union All
        Select 'CA',200

        Insert Into #Balance
        Select 'FL',100 Union All
        Select 'FL',200 Union All
        Select 'CA',300 Union All
        Select 'CA',200 Union All
        Select 'CA',100 

        ;with cteLoan
        AS(
            Select ROW_NUMBER() Over(Partition by State order by State) As Rn, * from #Loan
        )
        ,
        cteBalance
        AS(
            Select ROW_NUMBER() Over(Partition by State order by State) As Rn, * from #Balance
        )


        Select DISTINCT ISNULL(l.State,b.State) as State
        ,SUM(ISNULL(Loan,0)) As Loan
        ,SUM(ISNULL(Balance,0)) As Balance
        from cteLoan l
        FULL OUTER JOIN cteBalance b
        on l.State=b.State and l.rn=b.rn
        Group by ISNULL(l.State,b.State)

        Drop Table #Loan
        Drop Table #Balance
0 голосов
/ 29 августа 2018

Использовать подзапрос: сначала объедините таблицу ссуд и сальдо, а затем объедините таблицу состояний с результатом этой производной таблицы

SELECT 
  S.STATE AS STATE, Loan,Balance
FROM State AS S inner join
 (select L.state,sum(loan) as loan, sum(balance) as balance
 from Loan AS L INNER JOIN Balance AS B ON B.STATE = S.STATE
 GROUP BY L.STATE)X on s.state=x.state
0 голосов
/ 29 августа 2018

Можете ли вы попробовать это:

Select S.State, B.Balance,L.Loan from State S 
inner join (select state, sum(loan) as Loan from Loan group by state) L
inner join (select state, sum(balance) as Balance from Balance group by state) B
on L.state=S.state and B.State=S.State;
0 голосов
/ 29 августа 2018

Выполните агрегирование для каждой таблицы в отдельном подзапросе, затем присоединитесь:

SELECT 
  S.STATE AS STATE, 
  L.Loan,
  B.Balance
FROM State AS S
  LEFT JOIN (select state, sum(loan) as Loan
              from loan
              group by state) AS L ON L.STATE = S.STATE
  LEFT JOIN (select state, sum(Balance) as balance
              from balance
              group by state) AS B ON B.STATE = S.STATE

(ЛЕВЫЕ СОЕДИНЕНИЯ на случай, если в штате нет строк займа или баланса.)

0 голосов
/ 29 августа 2018

Попробуйте это:

SELECT S.STATE, L.Loan as TotalLoan, B.Balance as TotalBalance
FROM State AS S
LEFT JOIN (select STATE, sum(Loan) as Loan
           from Loan
           group by STATE) AS L
ON L.STATE = S.STATE

LEFT JOIN (select STATE, sum(Balance) as Balance
           from Balance
           group by STATE) AS B
ON B.STATE = S.STATE

Результат:

| STATE |TotalLoan|TotalBalance|
----------------------------
|    FL |   1100  |     300    |
|    CA |   1000  |     600    |
0 голосов
/ 29 августа 2018

Вы можете попробовать это, использовать UNION ALL объединить Balance и Loan таблицы и использовать небольшой навык,

  • Balance заполнить Loan набор столбцов 0
  • Loan заполнить Balance набор столбцов 0

затем JOIN с State до SUM

create table State(
  STATE varchar(50)
);



insert into State values ('FL'); 
insert into State values ('CA'); 
create table Balance(
  STATE varchar(50),
  Balance int
);



insert into Balance values ('FL',100);
insert into Balance values ('FL',200);
insert into Balance values ('CA',300);
insert into Balance values ('CA',200);
insert into Balance values ('CA',100);

create table Loan(
  STATE varchar(50),
  loan int
);

insert into loan values ( 'FL',500);
insert into loan values ( 'FL',600);
insert into loan values ( 'CA',700);
insert into loan values ( 'CA',100);
insert into loan values ( 'CA',200);

Запрос 1 :

SELECT s.STATE,SUM(t1.Loan) as 'Loan',SUM(t1.Balance) as 'Balance'
FROM 
(
  SELECT STATE,0 AS Loan,Balance  
  FROM Balance 
  UNION ALL
  SELECT STATE,Loan,0   
  FROM Loan 
) t1
INNER JOIN State s on s.STATE = t1.STATE
GROUP BY s.STATE

Результаты

| STATE | Loan | Balance |
|-------|------|---------|
|    CA | 1000 |     600 |
|    FL | 1100 |     300 |
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...