Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
基于ID和日期的SQL连接_Sql_Postgresql_Join - Fatal编程技术网

基于ID和日期的SQL连接

基于ID和日期的SQL连接,sql,postgresql,join,Sql,Postgresql,Join,我对如何基于日期和sku执行连接有点困惑 我有3个表,一个包含订单信息,一个包含行项目,一个包含成本 我可以加入行项目和订单信息以获得以下信息: Sku | Price | Date ------ | ------ | ----- ABC1 | 3.99 | 2016-11-01 ABC2 | 2.99 | 2016-10-01 ABC1 | 3.99 | 2016-10-01 ABC3 | 5.99 | 2016-11-01 Sku | Cost

我对如何基于日期和sku执行连接有点困惑

我有3个表,一个包含订单信息,一个包含行项目,一个包含成本

我可以加入行项目和订单信息以获得以下信息:

Sku    | Price  | Date
------ | ------ | -----
ABC1   | 3.99   | 2016-11-01
ABC2   | 2.99   | 2016-10-01
ABC1   | 3.99   | 2016-10-01
ABC3   | 5.99   | 2016-11-01
Sku    | Cost   | Valid_from | Valid_to
------ | ------ | ---------- | ----------
ABC1   | 1.99   | 2016-11-01 | NULL
ABC2   | 0.99   | 2015-10-01 | NULL
ABC1   | 2.99   | 2015-10-01 | 2016-10-30 
ABC3   | 3.99   | 2015-11-01 | 2016-10-30 
我需要根据订单日期计算货物的成本

它位于成本表中,如下所示:

Sku    | Price  | Date
------ | ------ | -----
ABC1   | 3.99   | 2016-11-01
ABC2   | 2.99   | 2016-10-01
ABC1   | 3.99   | 2016-10-01
ABC3   | 5.99   | 2016-11-01
Sku    | Cost   | Valid_from | Valid_to
------ | ------ | ---------- | ----------
ABC1   | 1.99   | 2016-11-01 | NULL
ABC2   | 0.99   | 2015-10-01 | NULL
ABC1   | 2.99   | 2015-10-01 | 2016-10-30 
ABC3   | 3.99   | 2015-11-01 | 2016-10-30 
一些SKU有多个成本记录,有开始和结束日期,其他SKU只有一个开始日期,没有结束日期

我正在努力查找sku,然后查找相应的日期

Sku    | Price  | Date       | Cost
------ | ------ | ---------- | -----
ABC1   | 3.99   | 2016-11-01 | 1.99
ABC2   | 2.99   | 2016-10-01 | 0.99
ABC1   | 3.99   | 2016-10-01 | 2.99
ABC3   | 5.99   | 2016-11-01 | 3.99
我可能正在尝试重新设计它,但似乎无法接近加入这些并获取相关信息


任何通知的帮助都需要在范围内的日期。但在这种情况下,需要两个条件来处理开放范围

 SELECT io.*, c.Cost
 FROM itemOrder io
 JOIN costs c
   ON io.Sku =  c.Sku
  AND ( (io.Date >= c.Valid_from  and c.Valid_to IS NULL)
     OR (io.Date >= c.Valid_from  and io.Date <= c.Valid_to)
      )                                    -- ^^ this may need to be `<`
                                           -- depend on how you define your ranges

您可以动态创建日期范围,然后测试行项目中的日期是否属于该范围:

select li.*, c.cost
from line_item li
  join cost c on li.sku = c.sku 
             and li.date <@ daterange(c.valid_from, c.valid_to);
注:


对于示例数据,上述查询不会返回SKU为ABC3的行项目的成本信息,因为该行项目的日期不在ABC3的成本行定义的范围内。如果您的示例数据是正确的,并且您确实希望包含行项目ABC3,那么您需要一个外部联接,但这样您就没有成本值了

有效的_To列显然是多余的,我强烈建议将其从表中删除

要获取订单日期的最新价格,请使用交叉应用top 1查询:

select o.sku, o.price, o.date, cx.cost
from order o
cross join lateral
(
  select cost 
  from  costs c
  where c.sku = o.sku and c.valid_from <= o.date
  order by date desc
  limit 1
) cx;

博士后没有交叉申请。它使用SQL标准的交叉连接。我也不同意有效的\u-to是多余的:它可以用来创建约束,以防止重叠的有效性间隔为什么说有效的\u-to是多余的?使用新的有效的\u-from记录,前一个有效的\u-from会自动过期。您有一个ABC1/2016-11-01条目和一个ABC1/2016-10-01条目。显然,有一个价格从2016年10月1日起生效,直到2016年11月1日前一天。如果您在记录中另外将此日期存储为有效日期,您可能会犯错误并存储例如2016-11-01,突然在同一天有两个有效价格。删除多余的列以避免此类数据不一致。@a_horse_和a_no_name:谢谢您的更正。@a_horse_和a_no_name:是的,因为ABC1上有两个订单,对于每一个,我们都在订单日查找成本。基本上,结果应该与horse Response相同,但他使用了一个我不知道的数据范围。查看daterange的教程,该索引应该类似于使用gist cost的汽车上创建索引车\u price\u range\u idx;和你写的一样吗?看起来在“成本”列上创建要点索引是非常困难的enough@JuanCarlosOropeza:成本列上的索引将完全无用。但你是对的,它应该是一个要点索引。对不起,我指的是日期栏。我正在查找的示例是一些范围之间的成本,索引位于成本列中。我认为现在应该创建一个范围索引。我认为应该有两个索引,一个用于li.date,另一个用于costValid\u from,Valid\u to任何人都知道如何确保上一个日期包含在内?截止日期发生变化的任何价格目前不包括在SKU ABC3行项目的日期范围内。2016-11-01年没有相应的成本条目在ABC3的成本范围结束后。因此,要么您的预期输出错误,要么样本数据错误。