Результат SQL (отличие) от двух отдельных таблиц - PullRequest
0 голосов
/ 25 октября 2011

У меня есть две таблицы -

ДОХОД

Id - ProjectId - inAmount 
1  - 2              200   
2  - 2              100
3  - 1              100
4  - 2              100
5  - 1              200

Расходы

Id - ProjectId - exAmount
1  - 2           50        
2  - 1           100
3  - 2           120
4  - 1           70

Теперь я хочу эти результаты

Результат

ProjectId - Total Income - Total Expense - Difference 
1           result         result          result
2           result         result          result

Помните: всю эту работу я должен выполнить в SQL

Я сделал общий доход, общие расходы, но как лучше отразить разницу?

----- отредактировано ......

Я пробовал это

SELECT sum(ex_amount) as expense, 
       sum(in_amount) as income,  
       sum(in_amount) - sum(ex_amount) as Difference,  
       project_name
FROM expense, 
     project, 
     income
WHERE expense.projectId = Project.id 
  AND income.ProejctId = Project.id
group by mh_name";

отредактировано второй раз

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

напишите свой ответ, используя эти поля

ДОХОД

in_id  - in_source -  in_amount 
    1  - 2              200   
    2  - 2              100
    3  - 1              100
    4  - 2              100
    5  - 1              200

Расходы

ex_id - mh_id -     ex_amount
    1  - 2           50        
    2  - 1           100
    3  - 2           120
    4  - 1           70

main_head или проект

mh_id -  mh_name
    1  -  abc
    2  -  ase
    3  -  czz
    4  -  xys

Примечание in_source = mh_id

В настоящее время я использую следующие запросы

для общего дохода на проект

SELECT sum(in_amount) as amount, mh_name FROM income, main_head WHERE income.in_source = main_head.mh_id group by mh_name Order By amount desc

общие расходы на проект

SELECT sum(ex_amount) as amount, mh_name FROM expense, main_head WHERE expense.mh_id = main_head.mh_id group by mh_name Order By amount desc

РЕШЕНО МНЕ ....

SELECT
mh_name,
 income - expense AS difference 
FROM 
(SELECT sum(in_amount) AS income, in_source FROM income GROPU BY in_source) AS t1, 
(SELECT sum(ex_amount) AS expense, mh_id FROM expense GROUP BY mh_id) AS t2, 
(SELECT * FROM main_head) AS t3 
WHERE 
t1.in_source = t2.mh_id 
AND
t1.in_source=t3.mh_id

Ответы [ 4 ]

2 голосов
/ 25 октября 2011

Этот SQL должен работать для вас:

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

SELECT i.ProjectId, 
       sum(inAmount) AS "Total Income",
       sum(exAmount) AS "Total Expense",
       (sum(inAmount) - sum(exAmount)) AS "Difference"
FROM   Income i
JOIN   Expense e
ON     i.project_id = e.project_id
GROUP BY i.ProjectId

Обновленный ответ, который отражает 0 - много доходов и 0 - много возможных расходов:

SELECT i.ProjectId, 
       i.income AS "Total Income",
       e.expense AS "Total Expense",
       (i.income - e.expense) AS "Difference"
FROM   (SELECT ProjectId, sum(inAmount) AS income FROM Income GROUP BY ProjectId) i
FULL OUTER JOIN   (SELECT ProjectId, sum(exAmount) AS expense FROM Income GROUP BY ProjectId) e
ON     i.project_id = e.project_id
2 голосов
/ 25 октября 2011
select 
    i.ProjectId, 
    sum(i.inamount) as TotalIncome, 
    sum(e.examount) as TotalExpense, 
    sum(i.inamount) - sum(e.examount) as Difference
from income i
inner join expense e
on i.projectid = e.projectid
group by i.projectid

РЕДАКТИРОВАТЬ: мы все были неправы.Поскольку объединения без подзапросов объединяют все совпадения, это дает нам дублированные результаты.Вот правильный ответ и правильные результаты, иначе вы получите двойные значения:

select 
    i.projectid,
    i.inamount as Income,
    e.examount as Expense,
    i.inamount - e.examount as [Difference]
from
(
    select projectid, SUM(inamount) as inamount
    from income
    group by projectid
) as i
full outer join
(
    select projectid, SUM(examount) as examount
    from expense
    group by projectid
) as e
on i.projectid = e.projectid

Я сохранил свой первоначальный ответ, чтобы их можно было сравнить.Второй запрос правильный.

1 голос
/ 25 октября 2011

Проблема, с которой столкнулась ваша попытка и несколько ответов, состоит в том, что вы объединяете наборы данных вместе.

Например, в проекте 2 есть 3 записи о доходах и 2 записи о расходах.На самом деле вы не хотите объединять их вместе, в результате вы получите 6 записей ...

Id - ProjectId - inAmount        Id - ProjectId - exAmount
1  - 2              200           1   2           50
2  - 2              100           1   2           50
4  - 2              100           1   2           50
1  - 2              200           3   2           120
2  - 2              100           3   2           120
4  - 2              100           3   2           120

Как видите, это приведет к серьезному дублированию.

ТамЕсть несколько стандартных подходов.Такие как коррелированные подзапросы или встроенные представления.


коррелированные подзапросы ...

SELECT
  *,
  (SELECT SUM(inAmount) FROM income  WHERE projectId = project.Id) AS income,
  (SELECT SUM(exAmount) FROM expense WHERE projectId = project.Id) AS expense
FROM
  project


встроенные представления

SELECT
  project.Id,
  income.inAmount,
  expense.exAmount
FROM
  project
LEFT JOIN
  (SELECT projectID, SUM(inAmount) AS inAmount FROM income  GROUP BY projectID) AS income
    ON income.projectID = project.ID
LEFT JOIN
  (SELECT projectID, SUM(exAmount) AS exAmount FROM expense GROUP BY projectID) AS expense
    ON expense.projectID = project.ID

EDIT

Исправление попытки Хамидама использовать UNION ...

SELECT
  projectID,
  SUM(inAmount),
  SUM(exAmount)
FROM
(
  SELECT projectID,      inAmount, 0 AS exAmount FROM income  GROUP BY projectID
  UNION ALL
  SELECT projectID, 0 as inAmount,      exAmount FROM expense GROUP BY projectID
)
  AS data
GROUP BY
  projectID
0 голосов
/ 25 октября 2011
SELECT ge.id AS ProjectID 
     , TotalIncome
     , TotalExpense
     , TotalIncome - TotalExpense AS Difference
FROM 
    ( SELECT p.id
           , COALESCE(SUM(i.in_amount), 0) AS TotalIncome
      FROM project p
        LEFT JOIN income i
          ON i.projectid = p.id
      GROUP BY p.id
    ) ge
  JOIN
    ( SELECT p.id
           , COALESCE(SUM(e.ex_amount), 0) AS TotalExpense
      FROM project p
        LEFT JOIN expense e
          ON e.projectid = p.id
      GROUP BY p.id
    ) gi
    ON ge.id = gi.id
...