SQL SELECT QUERY BY DATE

时间:2013-10-14 11:25:24

标签: mysql date

我有两个相关的表,其中有许多基于日期的记录。 我需要根据特定日期选择有效费率。

以下是数据示例:

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

3 个答案:

答案 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格式,例如。二零一三年十月十四日