如何用3个标签选择1个日期字段?

时间:2016-10-28 13:12:19

标签: sql oracle11g

我正在进行查询,选择1个日期字段3次。

SELECT t1.datefield date_1, 
       t1.datefield date_2, 
       t1.datefield date_3 
FROM   table t1 
WHERE  t1.datefield BETWEEN To_date('01/07/2016', 'dd/mm/yyyy') AND To_date('31/07/2016', 'dd/mm/yyyy') 

我要求date_1在7月1日到7月31日之间,date_2在8月1日到8月之间 8月31日,日期3月1日至9月30日。我怎么能这样做?

示例:

SELECT t1.date_invoice date_1, 
       t1.date_invoice date_2, 
       t1.date_invoice date_3 
FROM   invoices t1 
WHERE  t1.date_invoice BETWEEN To_date('01/07/2016', 'dd/mm/yyyy') AND To_date('31/07/2016', 'dd/mm/yyyy')

   DATE_1       DATE_2     DATE_3        
----------   ----------- -----------
01/07/2016   14/08/2016   15/09/2016 

但是表只有一个date_invoice

1 个答案:

答案 0 :(得分:1)

问题是您在查询中选择了同一日期,即使您给它三个不同的名称。当您从单个表中进行选择时,您将逐个获取其行。对于表中的每一行,您都会读取date_invoice值,并在结果的所有三列中插入一个值。然后你对这个值强加三个条件,条件(显然)相互矛盾,所以没有任何东西可以匹配。

您可能想要做的是同时查看基表中的三行 - 并检查第一行是在七月份,第二份是八月份,第三份是九月份。您可能仍然没有结果,或者只有一个,或者可能是几个结果(如果7月份有三张发票,8月份有一张发票,9月份有2张发票,则总共会得到3 * 1 * 2 = 6张结果)。

每当你需要从一个表中选择一行和从另一个表中选择一行时,这就是一个JOIN。在你的情况下,你想要三行,所以它是两个连接。你的桌子三次都是一样的;当你把一张桌子加到自己身上时,这叫做“自我加入”,第一次看到它时可能听起来很奇怪,但它很常见,与不同表之间的连接没什么不同。

现在,也许您在某个地方有一个order_id,并且您只查找同一order_id的三倍发票。然后你会有一个JOIN CONDITION - 这三行都有相同的order_id。或者,您可能首先过滤基表,只查看首先具有给定order_id的行。

无论如何,您提出问题的方式没有“加入条件” - 所有发票必须被考虑并相互匹配。这被称为CROSS JOIN或CARTESIAN JOIN,它在某些情况下非常有用;但是,通常您会看到这样的交叉连接实际上反映了对问题的错误解决方案(例如,错过了order_id上的连接条件 - 您将获得7月份一个订单的发票与8月份不同订单的发票相匹配)。

你想要的问题是你想要的是重复的交叉连接,如下所示:

SELECT t1.datefield date_1, 
       t2.datefield date_2, 
       t3.datefield date_3 
FROM   your_table t1 CROSS JOIN your_table t2 CROSS JOIN your_table t3 
WHERE  t1.datefield BETWEEN To_date('01/07/2016', 'dd/mm/yyyy') 
                                 AND To_date('31/07/2016', 'dd/mm/yyyy')
  AND  t2.datefield BETWEEN .... -- (dates for August)
  AND  t3.datefield BETWEEN .... -- (dates for September)