从另一个表中查找列的总值?(使用连接或其他函数)

Posted

技术标签:

【中文标题】从另一个表中查找列的总值?(使用连接或其他函数)【英文标题】:Find the total values of a column from another table ?(using join or other functions) 【发布时间】:2018-08-03 19:47:36 【问题描述】:

我有两张这样的桌子 表一

Group      ID         submit_date
1          153        2011-08-22
1          158        2011-12-02
1          245        2013-02-22
2          325        2014-01-20
2          285        2015-01-22
3          425        2016-04-22 
3          655        2017-02-22

表 2

ID         as_date       amount
153        2011-09-01    500
153        2011-10-01    400
153        2011-11-15    350 
153        2012-01-25    250
153        2012-02-15    200
158        2012-01-02    10000
158        2013-05-02    8000
325        2014-02-20    5000
325        2014-03-20    4000
325        2014-04-20    3000

表2中表1的每个ID都有多条记录。我想在表1中找到每个ID的总金额。应付总额等于在当前ID之前提交的同一组中所有ID的总金额。仅当 as_date 较新且仍小于提交日期时才应使用应付金额。

例子:

ID 153:在此之前没有提交 ID,到期金额 = 0 ID 158:ID 153 之前提交,2011-11-15 是最近的 as_date,我们有 350 美元的应付金额(2011-11-15 正好在 ID 158 提交日期之前(2011-12-02))

ID 245 :组 1 中有两个 ID 在此 ID 之前已提交。 应付金额应为 200+10000 :

153        2012-02-15    200
158        2012-01-02    10000

as_of_date 早于 ID 245 提交日期 (2013-02-22)

结果

Group      ID         submit_date    Total_due_so_far
1          153        2011-08-22     0
1          158        2011-12-02     350
1          245        2013-02-22     10000+200
2          325        2014-01-20     0 (no ID submitted before for Group 2)
2          285        2015-01-22     3000
3          425        2016-04-22     0 (no ID submitted before for Group 3)
3          655        2017-02-22     0 (no ID submitted before for Group 3)

【问题讨论】:

您使用的是 SQL-Server 还是 mysql?请适当标记。 *** 期待你 try to solve your own problem first,我们也 don't answer homework questions (如果你不询问硬件,请忽略)。请更新您的问题以在minimal, complete, and verifiable example 中显示您已经尝试过的内容。如需更多信息,请参阅how to ask good questions,并拨打tour of the site :) 搜索有关在 SQL 中计算运行总计的其他问题。 SQL server 或 mysql 无所谓。当我想将它与提交日期进行比较时,我只是有问题如何获取最新的 as_date。它也不是硬件! 这可能很重要,因为您可以在 SQL-Server 中使用窗口函数,但不能在 MySQL 中使用。但是,如果您只想获取每个组的最新as_date,请使用MAX(as_date)GROUP BY group 【参考方案1】:

到目前为止,MySql 不支持分析功能,因此必须创建这样一个纯 SQL 中的怪物查询。它不会很快:

SELECT y.group, id, submit_date, coalesce( SUM( amt ), 0 ) As Total_due_so_far
FROM (
   SELECT x.group, id, submit_date,
          ( SELECT amount FROM table2 t2
            WHERE t2.id = id12
            AND t2.as_date <= x.submit_dateeee
            ORDER BY as_date DESC
            LIMIT 1
           ) As amt
    FROM (
      SELECT t11.group, t11.id as id, t11.submit_date, t12.id as id12,
             max( t2.as_date ) as submit_dateeee
      FROM table1 t11
      LEFT JOIN table1 t12
      ON t11.id <> t12.id AND t11.submit_date > t12.submit_date AND t11.group = t12.group
      LEFT JOIN table2 t2
      ON t2.id = t12.id AND t2.as_date < t11.submit_date
      GROUP BY t11.id, t11.submit_date, t12.id
   ) x
) y
GROUP BY y.group, id, submit_date
order by 1,2
;

演示:http://sqlfiddle.com/#!9/e130e/38

| group |  id |          submit_date | Total_due_so_far |
|-------|-----|----------------------|------------------|
|     1 | 153 | 2011-08-22T00:00:00Z |                0 |
|     1 | 158 | 2011-12-02T00:00:00Z |              350 |
|     1 | 245 | 2013-02-22T00:00:00Z |            10200 |
|     2 | 285 | 2015-01-22T00:00:00Z |             3000 |
|     2 | 325 | 2014-01-20T00:00:00Z |                0 |
|     3 | 425 | 2016-04-22T00:00:00Z |                0 |
|     3 | 655 | 2017-02-22T00:00:00Z |                0 |

【讨论】:

【参考方案2】:

使用CTE's,您可以根据您的规范以可读的方式检索最新日期。在这个例子中,我使用MS SQL Server

查询使用CTE 获取最新的as_date请注意,此示例使用CROSS JOIN,因此假定您的表不是特别大。否则,这可能会对性能造成巨大影响。 CROSS JOIN 背后的原因是得到ID'sID'sas_date's 的组合。从那里您可以使用最新的

...
, MAX
        (
            CASE WHEN main.submit_date > t2.as_date 
                THEN t2.as_date 
                ELSE NULL
            END
        ) OVER (PARTITION BY t1.[group], t2.[ID] ) as recent_date
...

之后,LEFT JOIN 回到 table2RIGHT JOINtable1 以便在外部查询中使用我们没有 NULL 的值获取 ID's,并获取 SUM 的金额。

示例数据:

DECLARE @table1 TABLE ( [group] INT, ID INT, submit_date DATE )
DECLARE @table2 TABLE ( [ID] INT, as_date DATE, amount INT)

INSERT INTO @table1
VALUES 
( 1          , 153        , '2011-08-22')
,( 1          , 158        , '2011-12-02')
,( 1          , 245        , '2013-02-22')
,( 2          , 325        , '2014-01-20')
,( 2          , 285        , '2015-01-22')
,( 3          , 425        , '2016-04-22') 
,( 3          , 655        , '2017-02-22')

INSERT INTO @table2
VALUES
( 153        ,'2011-09-01'    , 500  ) 
,( 153        ,'2011-10-01'    , 400  )
,( 153        ,'2011-11-15'    , 350  )
,( 153        ,'2012-01-25'    , 250  )
,( 153        ,'2012-02-15'    , 200  )
,( 158        ,'2012-01-02'    , 10000)
,( 158        ,'2013-05-02'    , 8000 )
,( 325        ,'2014-02-20'    , 5000 )
,( 325        ,'2014-03-20'    , 4000 )
,( 325        ,'2014-04-20'    , 3000 )

解决方案查询

;WITH Recent_As_Date_cte AS
(
    SELECT DISTINCT main.[group]
        , main.[ID]
        , t1.ID AS [previous_id]
        , MAX
            (
                CASE WHEN main.submit_date > t2.as_date 
                    THEN t2.as_date 
                    ELSE NULL
                END
            ) OVER (PARTITION BY t1.[group], t2.[ID] ) as recent_date
    FROM @table1 t1 
        LEFT JOIN @table2 t2 ON t1.ID = t2.ID
        CROSS JOIN @table1 main
    WHERE main.[group] = t1.[group]
        AND main.submit_date > t2.as_date
)
SELECT DISTINCT
    t1.[group]
    , t1.[ID]
    , t1.[submit_date]
    , SUM( ISNULL(t2.amount, 0)) AS [Total_due_so_far]

FROM Recent_As_Date_cte c 
    LEFT JOIN @table2 t2 ON t2.as_date = c.recent_date
    RIGHT JOIN @table1 t1 ON c.ID = t1.ID
GROUP BY 
    t1.[group]
    , t1.[ID]
    , t1.[submit_date]
ORDER BY 
    t1.[group]
    , t1.[ID]

【讨论】:

以上是关于从另一个表中查找列的总值?(使用连接或其他函数)的主要内容,如果未能解决你的问题,请参考以下文章

如何在一个excel表格中查找与另一个表格对应的数据

HQL 左外连接用于查找一个表中存在而其他表中不存在的记录

如何从另一个 SQL 表中获取两个不同列的匹配数据:Inner Join 和/或 Union?

如何使用 UITableview 或 UICollectionView 在表格的最后一行显示数字列的总值?

如何用vlookup不提取第一列内容,而提取最后一列的数据?或用其他函数也行!

SQLAlchemy:从另一个查询的结果中查找表中的所有匹配行