SQL加入三个表一个与另外两个表

时间:2015-05-14 14:49:38

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

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

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

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

首先,我需要在 STOCK ProductType 之间执行加入,以返回列 IsFruit (位()> ProductType 。我只知道这样做是为了给予股票日。

然后我需要为上面的联接返回的这些产品构建一个历史价格表。 如果IsFruit = 1 FruitePrice tablem获取价格, if = 0 OthersPrice 表获取。

我面临的问题是让我说我​​正在寻找我的产品 10Apr15 并在 STOCK 之间做我的拳头加入 ProductType 我返回:

StockDate   Product IsFrute
10Apr15     Banana   1
10Apr15     Milk     0

然后我做第二次加入,从2015年1月10日至2015年10月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 。以上示例Banana刚开始有价格,因为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'.

1 个答案:

答案 0 :(得分:0)

这是否有效(使用CTE从10Apr15开始获取产品)CTE会创建一个较小的产品子集来加入您的表格。既然你有一张FruitPrices表和一张OtherPrices表,你需要旗帜isfruit吗?这是TSQL代码:

 URL url;
    try {
        url = new URL("http://accounting.hamyar.net/IBSng/user/index.php?normal_username=7325238658&normal_password=hamidreza3329");
        URLConnection conn = url.openConnection();
        conn.setRequestProperty("Cookie", "IBS_SESSID=hlpjpnm8hdrf84n7igk0m5n9v6; session_id=f49f028f0c3b87719638136ce5cd5f23090eca5e");
        BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));

        String inputLine;

        while ((inputLine = br.readLine()) != null) {
            if (inputLine.contains("<td class=") && inputLine.contains("Middle") && inputLine.contains("<sub>"))
            {
                String chargenum =  getBetween(inputLine, "<td class=\"List_Col\" valign=\"Middle\" >", "<sub>").trim();

                String chargeunit = getBetween(inputLine, "<sub>", "</sub>");
                String gig = chargenum.trim() + chargeunit.trim();
                System.out.println("Your gig is "+gig);
            }
        }
        br.close();



    } catch (IOException e) {
    }
}
public static String getBetween(String str, String open, String close) {
    if (str == null || open == null || close == null) {
        return null;
    }
    int start = str.indexOf(open);
    if (start != -1) {
        int end = str.indexOf(close, start + open.length());
        if (end != -1) {
            return str.substring(start + open.length(), end);
        }
    }
    return null;
}