我想选择日期在一年中特定周的项目。
例如:
public class DoubleFontSizeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
// increase font size 5 times
return (double)value*5;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
第44周是从星期一31/10到星期日06/11。
我知道用
获取周数SELECT item
FROM table
WHERE my_date in week 44
我该怎么做? 感谢。
答案 0 :(得分:4)
尝试:
SELECT item
FROM table
WHERE to_char( my_date, 'IW ) = '44'
有关详细信息,请参阅此链接:
https://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements004.htm#i34924
IW --->一年中的一周(1-52或1-53)基于ISO标准。
答案 1 :(得分:1)
使用ISO Weeks并非易事,因为第1周可以从前一年开始,1月的第一天可以算作第52周或第53周。
因此,只提供一年没有一年的数字可能不明确(第52,53,1周)。
我为了获得ISO周的第一天而找到的最佳功能是
NEXT_DAY(TO_DATE( yearNo || '0104', 'YYYYMMDD' ) - INTERVAL '7' DAY, 'MONDAY') + ( weekNo - 1 ) * 7
因此,根据您的需要,它将是
SELECT item
FROM table
WHERE my_date
between NEXT_DAY(TO_DATE( yearNo || '0104', 'YYYYMMDD' ) - INTERVAL '7' DAY, 'MONDAY') + ( weekNo - 1 ) * 7
AND 6 + (NEXT_DAY(TO_DATE( yearNo || '0104', 'YYYYMMDD' ) - INTERVAL '7' DAY, 'MONDAY') + ( weekNo - 1 ) * 7)
实际上,“完全错误证明”的方式就是这个:
FUNCTION ISOWeekDate(weekNo INTEGER, yearNo INTEGER) RETURN DATE DETERMINISTIC IS
res DATE;
BEGIN
IF weekNo > 53 OR weekNo < 1 THEN
RAISE VALUE_ERROR;
END IF;
res := NEXT_DAY(TO_DATE( yearNo || '0104', 'YYYYMMDD' ) - INTERVAL '7' DAY, 'MONDAY') + ( weekNo - 1 ) * 7;
IF TO_CHAR(res, 'fmIYYY') = yearNo THEN
RETURN res;
ELSE
RAISE VALUE_ERROR;
END IF;
END ISOWeekDate;
答案 2 :(得分:0)
如果my_date
列的数据类型实际上是VARCHAR2(它不应该是,但它通常是),那么您需要先将其转换为日期,然后再返回char(字符串)格式不同。然后,如果44不一定是数字,但它可能是计算的结果,或子查询,或另一个表中的值(如果它是NUMBER数据类型),那么你需要做你正在做的事情。这有什么问题?
select item
from your_table
where to_number(to_char(to_date(my_date,'MM/DD/YYYY'),'IW')) = 44;
也许您想知道这是否可以更有效地完成?因此,例如,您可以将where
条件写为
my_date between (something) and (something else)
允许在my_date
上使用索引?答案是否定的,如果my_date
是VARCHAR2格式 - 你仍然需要将它包装在to_date()
内,这样你就会丢失索引。
但是,您可以在to_date(my_date)
上构建一个索引函数,这也许可以帮助您进行其他查询。那么,使您的当前查询更有效的问题是有意义的。现在你遇到ISO周的复杂性没有很好地定义(你也不是说哪个YEAR),所以假设你希望日期在ISO第44周,无论它在哪一年。如果日期是纯日期(时间组件等于00:00:00),你可以这样做:
where to_date(my_date, 'MM/DD/YYYY') between
trunc(sysdate, 'iw') + 7 * (44 - to_number(to_char(sysdate, 'iw'))) and
trunc(sysdate, 'iw') + 7 * (44 - to_number(to_char(sysdate, 'iw'))) + 6
右侧有很多计算,但是对于表中的所有行,它们只执行一次;他们基本上没有时间。