【问题标题】:Construct an SQL query to populate one table using data from another构造一个 SQL 查询以使用另一个表中的数据填充一个表
【发布时间】:2013-08-02 02:26:34
【问题描述】:

这对于有 SQL 经验的人来说是一个挑战(在这种情况下是 MS-Access)

我有 2 张桌子:holdingsvaluations


holdings 包含特定帐户在给定日期持有的所有资产及其各自的价值。这些是字段:

id{primary key/auto-inc}, accountid {int}, holdingdate {date}, holdingid {int}, holdingvalue {double}

valuations 包含特定账户在给定日期的持有量总和。这些是字段:

id{primary key/auto-inc}, accountid {int}, valuationdate {date}, valuation {double}。


在 2012 年 1 月之后,对于 valuations 表中的每个 valuation,我在 holdings 表中都有相应的持股集合,其总和 = 估值。

在此日期之前,我只有估值,没有持股。


例如在valuations 我会有这样的记录:

id  |  accountid  |  valuationdate  |  valuation
------------------------------------------------
56  |  12345      |  2013-03-31     |  2000000

相应地,我将拥有这些资产(在此日期,此帐户的总资产为 valuation

id  |  accountid  |  holdingdate  |  holdingid  |  holdingvalue
---------------------------------------------------------------
250 |  12345      |  2013-03-31   |  16         |  1000000
251 |  12345      |  2013-03-31   |  38         |  500000
252 |  12345      |  2013-03-31   |  27         |  500000

如上所述,有些情况我只有valuations表中的记录,没有对应的馆藏。


为了简化/优化我的数据库结构,我想消除valuations 表,因为它本质上是通过简单地对给定日期的帐户资产求和来重复应该出现在holdings 表中的信息。为了获得客户未来的估值,我可以简单地将他们在给定日期的持有量相加,完全不需要 valuations 表。

我的目标是使用来自valuations 的数据填充holdings 表中不存在的日期。

基本上,如果某个帐号​​/估值日期组合不存在任何持股,则在该帐号/估值日期的持股表中插入与该日期估值相等的虚拟持股 (holdingid = 999)。

是否可以构造一个SQL查询来实现上述?

【问题讨论】:

  • 日期部分能不能再清楚一点
  • 我添加了一个示例,展示了一些与valuation 记录相对应的holdings。这是否澄清了您不确定的内容?

标签: sql ms-access


【解决方案1】:

您可以根据日期使用 WHERE NOT IN。

INSERT INTO holdings
(accountid, holdingdate, holdingid, holdingvalue)
SELECT accountid, valuationdate, NULL, valuation 
FROM valuations
WHERE valuationdate NOT IN (
  SELECT holdingdate 
  FROM holdings
)

我不知道您是否还需要一个 Id 列和一个 holdingid 列。你必须决定如何处理这些。

【讨论】:

    【解决方案2】:

    其中任何一个都可以工作:

    insert into holdings (accountid, holdingdate, holdingid, holdingvalue) 
    select v.accountid, v.valuationdate, 999, v.valuation
    from valuations v
    left join holdings h on h.accountid=v.accountid and h.holdingdate=v.valuationdate
    where h.holdingdate is null 
    
    EDIT: Corrected the second version to use a correlated WHERE clause.
    
    insert into holdings (accountid, holdingdate, holdingid, holdingvalue) 
    select v.accountid, v.valuationdate, 999, v.valuation 
    from valuations v
    where v.valuationdate not in (select distinct holdingdate from holdings where accountid=v.accountid)
    

    【讨论】:

    • 应该是INSERT INTO 而不仅仅是INSERT
    • v.column 是否通过 valuation v 得到允许? IE。给你一个简写名字?
    • @harryg 是的。你可以这样使用别名,但实际上不需要它们,我只是出于习惯使用别名来缩短查询时间。
    • 好的,到这里,要运行了。
    • @harryg 在运行之前复制数据库!
    猜你喜欢
    • 2020-06-07
    • 2013-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-14
    • 1970-01-01
    相关资源
    最近更新 更多