【问题标题】:SQL Join three tables one vs. others twoSQL 连接三个表 1 vs. 其他 2
【发布时间】:2015-05-14 14:49:38
【问题描述】:

我将下面的示例代码作为我所面临的示例。

让我们说一个有这个表: STOCK :我每天都有我当前的库存图片。 ProductType :如果我的库存中的产品是水果,我在哪里可以获得信息。 FruitPrices :我有每个水果价格的历史价格。 OthersPrices:我有其他类型产品的历史价格。

我需要一个给定的库存日期加载所有历史价格,无论是水果还是其他。

所以首先我需要在 STOCKProductType 之间进行 Join 以返回列 IsFruit(位ProductType 列)。而且我只知道这样做是为了捐赠股票日。

然后我需要为 My above join 返回的这个产品建立一个历史价格表。 如果 IsFruit = 1FruitePrice 表中获取价格,if = 0OthersPrice 表中获取。

我面临的问题是,假设我要在 Apr15 的 Stock 上寻找我的产品,并在 STOCK 之间进行我的拳头 join ProductType 我返回:

StockDate   Product IsFrute
10Apr15     Banana   1
10Apr15     Milk     0

然后我执行第二次加入,从 1015 年 1 月 10 日到 2015 年 4 月 10 日从各自的表中返回香蕉和牛奶价格。

我希望这样看香蕉和牛奶的历史价格:

StockDate PriceDate Product Price
10Apr15   10Jan15 Banana     NULL
10Apr15   10Jan15 Milk       4
10Apr15   11Jan15 Banana     7
10Apr15   11Jan15 Milk       11
10Apr15   ...     Banana     8
10Apr15   ...     Milk       3
10Apr15   10Apr15 Banana     5
10Apr15   10Apr15 Milk       2

我可能没有丢失产品历史价格的日期,这种情况应该返回 NULL。上面的例子香蕉从 11Jan15 开始有价格,那么 10Jan15 应该返回 NULL

最后,我遇到的问题是,我在上面的表格中为每个组合在日期上有一行,例如 n x n x n。

举例说明我在做什么:

Select GP.PriceDate, GP.ProdName, case(GP.IsFrute = 1, FP.Price, else OP.Price)
(
    Select STK.PriceDate, STK.ProdName, PT.IsFrute
    from Stock as STK
    Join ProductType as PT on PT.ProdName = STK.ProdName
) as GP
join FruitPrice as FP on FP.Name = GP.ProdName
join OthersPrice as OT on OP.Name = GP.Name
Where GP.PriceDate = '10Apr15'
and FP.Date >= '10Jan15' and FP.Date <= '10Apr15'
and OT.Date >= '10Jan15' and OT.Date <= '10Apr15'

我的真实数据,分解每个表格的日期以显示正在发生的事情:

Refdate     Date        Date    Price
2015-05-13  2015-05-04  NULL    2650.000000000000
2015-05-13  2015-05-05  NULL    2650.000000000000
2015-05-13  2015-05-06  NULL    2650.000000000000
2015-05-13  2015-05-07  NULL    2460.000000000000
2015-05-13  2015-05-08  NULL    2490.000000000000
2015-05-13  2015-05-11  NULL    2660.000000000000
2015-05-13  2015-05-12  NULL    2660.000000000000
2015-05-13  2015-05-13  NULL    2770.000000000000
2015-05-13  2015-05-14  NULL    2610.000000000000
2015-05-13  2014-12-31  2015-05-06  1490.000000000000
2015-05-13  2014-12-31  2015-05-07  1490.000000000000
2015-05-13  2014-12-31  2015-05-08  1490.000000000000
2015-05-13  2014-12-31  2015-05-11  1490.000000000000
2015-05-13  2014-12-31  2015-05-12  1490.000000000000
2015-05-13  2014-12-31  2015-05-13  1490.000000000000
2015-05-13  2014-12-31  2015-05-14  1490.000000000000
2015-05-13  2014-12-31  2015-05-05  1490.000000000000
2015-05-13  2015-01-02  2015-05-06  1490.000000000000
2015-05-13  2015-01-02  2015-05-07  1490.000000000000
2015-05-13  2015-01-02  2015-05-08  1490.000000000000
2015-05-13  2015-01-02  2015-05-11  1490.000000000000
2015-05-13  2015-01-02  2015-05-12  1490.000000000000

更新 2: 真实查询

With cte_RiskFactors(RiskFactor)
AS
(Select RiskFactor, ProdId, from Exposure where Refdate = '20150513')
Select Expo.refdate, expo.riskfactor, expo.ProdId, px.price
from cte_RiskFactors as cte
join Exposure as expo on cte.RiskFactor = expo.RiskFactor
join Prices as px on px.Id_Product = cte.ProdId
where px.[Date] >= '20150501' and px.[Date] <= '20150513'
UNION
Select Expo.refdate, expo.riskfactor, iv.Value
from cte_RiskFactors as cte
join Exposure as expo on cte.RiskFactor = expo.RiskFactor
join IndexesValue as iv on iv.Id_RiskFactor = cte.IdRF
where iv.[Date] >= '20150501' and iv.[Date] <= '20150513'

错误:

Msg 207, Level 16, State 1, Line 62
Invalid column name 'IdRF'.
Msg 207, Level 16, State 1, Line 59
Invalid column name 'price'.

【问题讨论】:

  • 你能具体谈谈你的问题吗?预期结果是什么,实际结果是什么?你能把它们展示在一张桌子上吗? IMO 一个好的问题会包括一些具体的问题,例如“这个价格不应该为空,它应该是 X,因为 Y 的原因”。还可以考虑在 www.sqlfiddle.com 上添加一个示例
  • 我收到了 stockdate、fruitdate 和 othersdate 的每个组合的一行。
  • 现在包含在最后。

标签: join subquery sql-server-2014-express


【解决方案1】:

这是否可行(使用 CTE 获取截至 2015 年 4 月 10 日的产品)CTE 创建一个较小的产品子集来加入您的表。既然你有一个 FruitPrice 表和一个 OtherPrices 表,你需要标志 isfruit 吗?下面是 TSQL 代码:

WITH cte_products( ProdName)
AS
(SELECT Prodname FROM Stock WHERE PriceDate = '10Apr15')
SELECT STK.PriceDate, STK.ProdName, Coalesce(FP.Price,OP.Price)
FROM cte_products cte   
JOIN Stock STK ON cte.Prodname = STK.Prodname
LEFT OUTER JOIN FruitPrice FP ON cte.Prodname = FP.Name
LEFT OUTER JOIN Othersprice OP ON cte.Prodname = OP.Name
WHERE STK.PriceDate >= '10Jan15' and STK.PriceDate <= '10Apr15'

【讨论】:

  • 你在哪里检查 ProcutType 表中的 IsFruit = 1?
  • 我假设 FruitPrice 表仅包含水果的产品名称和价格,而表 Otherprice 仅包含其他产品的产品名称和价格,而不是水果。这是一个正确的假设吗?
  • 如果是这种情况,那么就不需要 isfruit 标志...因为您已经在这两个表中拥有了所需的所有信息。
  • 我的错,让我们说真的 wen 它的果实我使用 Prodname 进行我的加入,当它的其他我将使用来自 STOCK 的其他列时,可以说 Prodname2。这就是为什么我需要先加入表 ProductType 来检查它是水果还是其他。我在我的真实查询中包含了一个 update2
  • 请注意,我需要验证它的 Fruit 是否是 Product 可以有一个与 FruitsPrice 表匹配的 Prodname 并且还有一个与 OthersPrice 表匹配的 Productname2,我不想两次返回它知道应该使用什么的标准是 IsFruit = 1 我去 Prodname 并加入 FruitPrice 如果 IsFruit = 0 我使用 Prodname2 加入 OthersPrice
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多