如何连接两个没有重复的表

时间:2013-09-04 16:26:39

标签: mysql join

我有一个income表,如下所示:

date              income      
---------------------------
09/05/13          56000    
09/05/13          66600
09/05/13          50000

一个expense表,如下所示:

date              expense 
----------------------------
09/05/13          68800

我想编写一个输出如下的查询:

date              income             expense 
---------------------------------------------
09/05/13          56000              68800
09/05/13          66600
09/05/13          50000

来自income.income的每个值和来自expense.expense的每个值仅出现一次。 (如果我进行简单的连接,那么每个都会出现三次,因为income.dateexpense.date有重复的值。)

5 个答案:

答案 0 :(得分:2)

如果您尝试这样没有任何唯一ID,那么您的完整概念就错了。在表格中添加一些唯一的ID并进行必要的编码。

如果您有如下所示的表结构,则可以使用简单的equi join编写查询。 Income_tbl:

date              income  id    
---------------------------
09/05/13          56000   1 
09/05/13          66600   2
09/05/13          50000   3

Expense_tbl:

date              expense  id
----------------------------
09/05/13          68800    1
09/05/13                   2
09/05/13                   3

(或)尝试@Brian Hoover的查询它会起作用。

 SELECT income.date_col, income.income, expense.expense
FROM (
        SELECT i.date_col, i.income, @curRow := @curRow + 1 AS row_number
        FROM Income_tbl i
        JOIN (SELECT @curRow := 0) r
     ) AS income
JOIN (
        SELECT e.date_col, e.expense, @curExpenseRow := @curExpenseRow + 1 AS row_number
        FROM Expense_tbl e
        JOIN (SELECT @curExpenseRow := 0) r
     ) AS expense
ON income.row_number = expense.row_number;      

答案 1 :(得分:0)

最简单的方法是计算总和(按日期分组)并加入它们。您需要三个查询来表示您拥有的三个数据集:日期设置,收入集和费用集。

首先:设定日期

select distinct `date`
from (select `date` from income union select `date` from expense)

第二:收入集:

select `date`, sum(i.income) as income
from income as i
group by `date`

第三:费用设定:

select `date`, sum(e.expense) as expense
from expense as e
group by `date`

最后:把它们放在一起:

select 
    d.date, i.income, e.expense
from
    (
        select distinct `date` 
        from (select `date` from income union select `date` from expense)
    ) as d
    left join (
        select `date`, sum(i.income) as income
        from income as i
        group by `date`
    ) as i on d.`date` = i.`date`
    left join (
        select `date`, sum(e.expense) as expense
        from expense as e
        group by `date`
    ) as e on d.`date` = e.`date`

答案 2 :(得分:0)

这将为您提供所要求的输出,但它真的很脆弱。

SELECT income.date, income.income, expense.expense
FROM (
SELECT i.date, i.income, @curRow := @curRow + 1 AS row_number
FROM income i
JOIN (SELECT @curRow := 0) r) AS income
JOIN (
SELECT e.date, e.expense, @curExpenseRow := @curExpenseRow + 1 AS row_number
FROM expense e
JOIN (SELECT @curExpenseRow := 0) r) AS expense
ON income.row_number = expense.row_number

SQL Fiddle

假设您的收入和费用行数相同,收入和费用的顺序相同,因此它按行号合并结果。

您真正需要的是某种方式来加入收入和支出,可能是每个行的分类帐条目ID。与我发布的查询中的被黑客连接相比,这将为您提供明确的连接。

答案 3 :(得分:0)

如果您想要单独输入,则需要以下内容:

select date, income, expense
from
  (
    select
      if(@iId_last = incomeId, null, a.income) as income,
      if(@eId_last = expenseId, null, a.expense) as expense,
      a.date,
      @iId_last := a.incomeId as incomeId,
      @eId_last := a.expenseId as expenseId
    from 
      (select @d := '0000-00-00', @iId_last := -1, @eId_last := -1) as init,
      (
        select 
          d.*, 
          coalesce(i.incomeId,0) as incomeId, income, 
          coalesce(e.expenseId,0) as expenseId, expense
        from
          (
            select distinct date from (select incomeDate as date from income union select expenseDate as date from expense) as d
          ) as d
          left join income as i on d.date = i.incomeDate
          left join expense as e on d.date = e.expenseDate
        order by d.date, incomeId, expenseId
      ) as a
    order by date, incomeId, expenseId
  ) as r;

请注意,此解决方案要求incomeexpense表都具有Id。检查SQL Fiddle solution(我已经测试了一些组合:许多收入行和一个费用行,一个收入行和许多费用行,没有收入行和一些费用行,一个收入行和没有费用行。)

答案 4 :(得分:0)

如果您不关心收入值与费用值匹配的特定订单,您可以通过此类查询获得所需的输出

SELECT date, 
       MAX(CASE WHEN type = 1 THEN amount END) income,
       MAX(CASE WHEN type = 2 THEN amount END) expense
  FROM
(
  SELECT 1 type, date, income amount, @n := IF(@g = date, @n + 1, 1) rnum, @g := date g
    FROM income CROSS JOIN (SELECT @n := 0, @g := NULL) i1
   UNION ALL
  SELECT 2, date, expense amount, @m := IF(@f = date, @m + 1, 1) rnum, @f := date g
    FROM expense CROSS JOIN (SELECT @m := 0, @f := NULL) i2
) q
 GROUP BY date, rnum

输出:

|               DATE | INCOME | EXPENSE |
|--------------------|--------|---------|
| September, 05 2013 |  56000 |   68800 |
| September, 05 2013 |  66600 |  (null) |
| September, 05 2013 |  50000 |  (null) |

这是 SQLFiddle 演示