订购日期并根据当前日期(出生日列表)SQLite检索结果

时间:2013-12-02 04:34:30

标签: android sqlite date

我在Sqlite列中有一个以字符串形式存储的日期,格式为YYYY-MM-DD(年份日期和月份不分为三列)现在我需要进行一个查询,它给出了我的结果最接近查询日期的日期作为第一个条目,订单按升序排列。这里我对这一年不感兴趣,只有月份和日期很重要。根据我的要求,我应该处理什么类型的查询,以便按顺序获取这些日期。

示例:

我有日期

1980-01-11,1999-08-03,2013-12-03 在查询之后我应该得到:(基于当前日期,考虑它是2013年12月1日)

2013-12-03,1999-01-11,1980-08-03(仅按月和日排序)。

我也从这里参考:MySQL query to sort upcoming birthdays based on current date但是不太清楚。我认为Unix时间戳作为存储在日期列中的长值将有助于我感兴趣的查询类型,而不是简单的日期格式。

2 个答案:

答案 0 :(得分:5)

以下将做:

SELECT *
FROM _table
ORDER BY SUBSTR(DATE('NOW'), 6)>SUBSTR(birthdate, 6), SUBSTR(birthdate, 6)

SQL Fiddle中查看。

SUBSTR(date, 6)将删除年份部分。出生日期必须按MM-DD排序,但首先应显示将在今天之后发生的事件,然后显示在今天之前发生的事件。

SUBSTR(DATE('NOW'), 6)>SUBSTR(birthdate, 6)将为生日MM-DD返回0,大于或等于今天MM-DD,否则为1。因此,第一个表达式将ORDER在提交日期之后的过去日期。仅ORDER的第二个参数日期为MM-DD

SQL Fiddle中逐步查看。

答案 1 :(得分:2)

有很多方法可以做到,有些方法比其他方法更有效。我将建议一个可以在不改变数据库格式的情况下有效的解决方案,但请注意,如果您可以使用单独的Year,Month,Day整数列,​​或者可以使用单独的Year,Month,Day整数列,​​它们都可以更快(特别是如果我们讨论的是大生日列表)一个unix时间戳列。

select *, 
strftime('%j', 
    strftime('%Y', 'now') || '-' || 
    strftime('%m', birthday) || '-' || 
    strftime('%d', birthday)
)
- strftime('%j', 
    strftime('%Y', 'now') || '-' || 
    strftime('%m', 'now') || '-' || 
    strftime('%d', 'now')
)
as daydiff
from users
where daydiff >=0

union all

select *, 
strftime('%j', 
    strftime('%Y', 'now') || '-' || 
    strftime('%m', birthday) || '-' || 
    strftime('%d', birthday)
)
- strftime('%j', 
    strftime('%Y', 'now','+1 year') || '-' || 
    strftime('%m', 'now') || '-' || 
    strftime('%d', 'now')
) + 366
as daydiff
from users
where daydiff <366
order by daydiff

以上使用今天的年份和每个用户的月和日部分来计算一年中的某一天(例如今天的2013年12月11日是345天)并减去今天的日期。当年发生的生日将具有daydiff值&gt; = 0,因此我们首先使用它们。这是union的第一部分。

第二部分进行相同的计算,但是对于明年生日的人,我们在daydiff值中添加366,并确保我们只得到第一部分没有得到的字段。

可以使用CASE WHEN而不是union重写相同的查询。 CASE替代方案会更快,因为它只会从users表中获取一次,而不是两次,但是在这个论坛中编写它真的很难看。第二个想法,无论如何我会写它,因为它更快

select *, 
CASE WHEN 
  strftime('%j', 
    strftime('%Y', 'now') || '-' || strftime('%m', birthday) || '-' || strftime('%d', birthday)
  )
  - strftime('%j', 
    strftime('%Y', 'now') || '-' || strftime('%m', 'now') || '-' || strftime('%d', 'now')
  ) >= 0
THEN 
  strftime('%j', 
    strftime('%Y', 'now') || '-' || strftime('%m', birthday) || '-' || strftime('%d', birthday)
  )
  - strftime('%j', 
    strftime('%Y', 'now') || '-' || strftime('%m', 'now') || '-' || strftime('%d', 'now')
  ) 
ELSE 
  strftime('%j', 
    strftime('%Y', 'now') || '-' || strftime('%m', birthday) || '-' || strftime('%d', birthday)
  )
  - strftime('%j', 
    strftime('%Y', 'now') || '-' || strftime('%m', 'now') || '-' || strftime('%d', 'now')
  ) + 366 
END
as daydiff
from users
order by daydiff

也是最后一点。我在明年的生日时手动添加了366,但正确的做法是根据年份(365或366)添加一年中的日期。由于我们只需要它进行订购,这不会造成麻烦,因为最坏的情况是它会为明年的所有用户添加一个daydiff。所以'2013-12-31'的生日会给daydiff = 20,但'2014-01-01'的生日会给daydiff = 22。

编辑:

这是fiddle