从另一个表中查找列的总值?(使用连接或其他函数)
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's
到ID's
和as_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
回到 table2
和 RIGHT JOIN
到 table1
以便在外部查询中使用我们没有 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]
【讨论】:
以上是关于从另一个表中查找列的总值?(使用连接或其他函数)的主要内容,如果未能解决你的问题,请参考以下文章
如何从另一个 SQL 表中获取两个不同列的匹配数据:Inner Join 和/或 Union?
如何使用 UITableview 或 UICollectionView 在表格的最后一行显示数字列的总值?