我有两个相关的表,其中有许多基于日期的记录。 我需要根据特定日期选择有效费率。
以下是数据示例:
on HEADERTABLE ...
ID, PICKUP, DELIVERY, VALIDFROM, VALIDTO, COMMODITY, CARRIER 1, NEW YORK, CHICAGO, 01-OCT-13,31-OCT-13, FOOTWEAR, DHL 2, NEW YORK, CHICAGO, 20-OCT-13,31-OCT-13, FOOTWEAR, UPS 3, NEW YORK, CHICAGO, 30-OCT-13,31-OCT-13, FOOTWEAR, DHL 4, NEW YORK, CHICAGO, 30-OCT-13,31-OCT-13, WOODEN PRODUCTS, DHL
on linestable:
ID, HEADERTABLEID, RATEDESC, RATE 2325, 1, DELIVERY, 1000 2354, 2, DELIVERY, 1500 2355, 2, TAX, 100 2355, 3, DELIVERY, 1200 2356, 3, TAX, 110 2380, 4, DELIVERY, 1000
因此,通过使用某个日期(下面的日期变量),我只需要显示一个选项。例如,如果日期= 25-oct-13,那么要显示的记录是Id 2(来自linestable中的headertable +链接速率)
如果日期= 10-oct-13,那么选项1就是要显示的那个。
如果日期= 30-oct-13,则会显示2条记录(Id 3和4)(区别为商品)
这是我正在使用的代码(我尝试了很多其他代码,没有运气)但显然有一些东西丢失,因为它显示了所有记录。
感谢任何帮助。
SELECT * from schema1.headertable, schema1.linestable
WHERE headertable.Id= linestable.headertableId
AND headertable.Validfrom <= STR_TO_DATE('" & thedate & "','%Y-%m-%d')
AND headertable.Validto >= STR_TO_DATE('" & thedate & "','%Y-%m-%d')
AND headertable.PICKUP LIKE '%NEW YORK%'
AND headertable.DELIVERY LIKE '%CHICAGO%'
ORDER BY headertable.Validfrom DESC, linestable.Id DESC
答案 0 :(得分:1)
要仅返回结果集中的第一条记录,请将LIMIT 1
附加到查询的末尾。
答案 1 :(得分:1)
好的,让我们以结构化的方式解决这个问题,与我们使用结构化查询语言的想法一致。
首先,我们需要从headertable
中获取与您的日期匹配的行。此处的查询http://sqlfiddle.com/#!2/dff43/4/0会选出headertable
中的匹配行。这些行有两个。
SELECT headertable.*
FROM ( SELECT STR_TO_DATE('2013-10-25', '%Y-%m-%d') AS thedate) d
JOIN headertable
WHERE headertable.Validfrom <= thedate
AND headertable.Validto >= thedate
AND headertable.PICKUP LIKE '%NEW YORK%'
AND headertable.DELIVERY LIKE '%CHICAGO%'
注意SELECT STR_TO_DATE(...
的小技巧。这允许我们将thedate
参数只放入查询一次,并多次使用它。
但是你的规范只需要其中一行而不是两行。我们必须通过选择匹配的最新 Validfrom
日期来消除歧义。
让我们试着找到正确行的Validfrom
日期。 http://sqlfiddle.com/#!2/dff43/6/0这回到10月20日。
SELECT MAX(Validfrom) AS Validfrom
FROM ( SELECT STR_TO_DATE('2013-10-25', '%Y-%m-%d') AS thedate) d
JOIN headertable
WHERE headertable.Validfrom <= thedate
AND headertable.Validto >= thedate
AND headertable.PICKUP LIKE '%NEW YORK%'
AND headertable.DELIVERY LIKE '%CHICAGO%'
所以,现在我们必须找到使用此日期给出“最佳”匹配的单行。以下是如何执行此操作:http://sqlfiddle.com/#!2/dff43/14/0
SELECT headertable.*
FROM (
SELECT STR_TO_DATE('2013-10-25', '%Y-%m-%d') AS thedate,
'%NEW YORK%' AS PICKUP,
'%CHICAGO%' AS DELIVERY
) AS d
JOIN headertable
WHERE Validfrom <= thedate
AND Validto >= thedate
AND PICKUP LIKE d.PICKUP
AND DELIVERY LIKE d.DELIVERY
AND ValidFrom IN /* disambiguate */
(
SELECT MAX(Validfrom) AS Validfrom
FROM headertable
WHERE Validfrom <= thedate
AND Validto >= thedate
AND PICKUP LIKE d.PICKUP
AND DELIVERY LIKE d.DELIVERY
)
这个查询有点像毛球。但是你的业务规则也是如此。
最后,我们必须加入你的另一张桌子。与日期选择逻辑相比,这非常简单。 http://sqlfiddle.com/#!2/dff43/17/0我们将使用JOIN
语法而不是逗号语法,因为它使查询逻辑更清晰。
SELECT headertable.*, linestable.*
FROM (
SELECT STR_TO_DATE('2013-10-25', '%Y-%m-%d') AS thedate,
'%NEW YORK%' AS PICKUP,
'%CHICAGO%' AS DELIVERY
) AS d
JOIN headertable
JOIN linestable ON headertable.Id = linestable.headertableId
WHERE Validto >= thedate
AND headertable.PICKUP LIKE d.PICKUP
AND headertable.DELIVERY LIKE d.DELIVERY
AND ValidFrom IN
(
SELECT MAX(Validfrom) AS Validfrom
FROM headertable
WHERE Validfrom <= thedate
AND Validto >= thedate
AND PICKUP LIKE d.PICKUP
AND DELIVERY LIKE d.DELIVERY
)
这似乎适用于您的30-oct-2013日期。 http://sqlfiddle.com/#!2/dff43/19/0
注意:我认为此日期含糊不清会显示您的业务规则存在问题。在我看来,您的ValidFrom和ValidTo日期可能不会重叠。
答案 2 :(得分:0)
试试这个
SELECT * from schema1.headertable, schema1.linestable
WHERE headertable.Id= linestable.headertableId
AND STR_TO_DATE('" & thedate & "','%Y-%m-%d') between headertable.Validfrom and DATE_ADD(headertable.Validto, INTERVAL 1 DAY)
AND headertable.PICKUP LIKE '%NEW YORK%'
AND headertable.DELIVERY LIKE '%CHICAGO%'
ORDER BY headertable.Validfrom DESC, linestable.Id DESC
还要确保数据类型正确:Validfrom和ValidTo应该是date;日期应为Y-m-d格式,例如。二零一三年十月十四日