查询销售额,按周分组

时间:2017-06-03 03:06:52

标签: sql sqlite fmdb

我试图在SQLLite中为我的应用程序整理查询,并希望请求一些帮助。

我想写的查询:

"我是UserID x的用户。对于我个人工作周,可以在我想要的任何一天开始(星期日到星期六,星期一到星期日等),我想看看哪个工作周是我最糟糕的,这是我最好的,就其而言销售。

保持简单"最差"和#34;最好"仅表示该周的最高和最低销售额。

如果每个人的工作周都在周日开始,这很容易,但事实并非如此。我必须克服SQL挑战,即分组数据库表中的所有行,而不仅仅是按周,而是自定义周(用户定义哪一天开始和结束一周)。

例如,如果我的工作周从星期日开始,那么在过去的一周,5月28日的星期是星期日,这是我工作周的开始(并且它将于6月3日星期六结束)。我会按照这种模式对表中的所有记录进行操作。

但是,不同的用户可以在5月29日星期一开始工作,并在6月2日星期五结束。

所以这意味着对于用户1,我想要从星期日的开始日和星期六的结束日对其行进行分组(然后将它们全部汇总,并获取销售的第一个和最后一个记录)

但是,对于用户2,我想在星期一到星期日的日期范围内对其记录进行分组

这是我到目前为止所处的位置。我觉得我很接近。

(请注意,我将日期存储为unix时间戳,以毫秒为单位,因此除以1000和unixepoch部分)。 + d部分实际上是基于当天开始的整数,但我还没弄清楚这个数字应该是什么。就在我认为我得到它的时候,其他人今天就失败了。

SELECT 'Date', SUM(Amount) 'Amount'  
FROM Sales WHERE UserID = x
GROUP BY CAST(( julianday((datetime(CreationDate / 1000, 'unixepoch', 'localtime')) + d) / 7 ) AS INT) 

有人认为他们可以帮我一把吗? :)

非常感谢!

修改

非常感谢你的帮助!

对于+ d问题(价值' d'要抵消)? 这是我在测试后发现的,这就是我能说的。我知道Sqllite使用0作为星期日,1作为星期一等,我知道我们正在分组并除以7(本周7天),但任何想法为什么这些将是正确的值' d&# 39;作为抵消?它似乎现在正在运作。我看到模式是2,1,0,6,5,4,3,但有点奇怪的顺序进入呃?

if (day == Sunday) //if your work week starts on Sunday, d=2
     return 2
else if (day == Monday)
     return 1
else if (day == Tuesday)
     return 0
else if (day == Wednesday) 
     return 6
else if (day == Thursday) 
     return 5
else if (day == Friday) 
     return 4
else if (day == Saturday) 
     return 3

2 个答案:

答案 0 :(得分:1)

你非常接近。

  1. 您要将d添加到日期时间。我不知道这是否会增加天数。我不知道如果在SQLite中向日期时间添加一个整数会发生什么。要播放保存,请将日期添加到朱利安日。你不必首先得到一个约会时间,顺便说一下这个朱利安的日子,你可以一步到位:

    julianday(CreationDate / 1000, 'unixepoch', 'localtime') + d
    

    这是我在查询中看到的唯一真正的缺陷。

  2. 朱利安日是一个分数,例如2457907.5。当您使用/调用分区时,您会得到一个小数结果。我看到你将这个结果转换为INT,但是我建议首先转换为INT,然后再进行除法,这将使得它成为一个整数除法。

    演员(julianday(CreationDate / 1000,' unixepoch',' localtime')+ d as int)/ 7

    这只是为了可读性;我得到一个天数(2457907而不是一些小数2457907.5)和整数除以7(例如2457907/7 = 351129)。

  3. 整个查询:

    SELECT 
      MIN(DATE(CreationDate / 1000, 'unixepoch', 'localtime')) AS from_date, 
      MAX(DATE(CreationDate / 1000, 'unixepoch', 'localtime')) AS till_date, 
      SUM(Amount) AS total
    FROM Sales 
    WHERE UserID = x
    GROUP BY CAST(JULIANDAY(CreationDate / 1000, 'unixepoch', 'localtime') + d as INT) / 7
    ORDER BY SUM(Amount);
    

    from_datetill_date并不总是代表整整七天,但只代表工作日(例如,从周日到周六的一周,但仅在周一,周三和周五工作) ,它会显示星期一和星期五的日期)。显示真实的一周需要稍微多一点的工作。 (我现在最好不要尝试这样做,因为在无法尝试查询的情况下很容易休息一天。)

    编辑:以下是我在本周开始和结束日的尝试。当我们在浮点值上调用DATE时,该值被视为儒略日。 (也许它也适用于整数,我无法从文档中确定。)

    SELECT 
      DATE(CAST(CAST(JULIANDAY(CreationDate / 1000, 'unixepoch', 'localtime') + d as INT) / 7 as REAL)) AS from_date,
      DATE(CAST(CAST(JULIANDAY(CreationDate / 1000, 'unixepoch', 'localtime') + d as INT) / 7 as REAL), '+6 day') AS till_date,
      MIN(DATE(CreationDate / 1000, 'unixepoch', 'localtime')) AS first_working_day, 
      MAX(DATE(CreationDate / 1000, 'unixepoch', 'localtime')) AS last_working_day, 
      SUM(Amount) AS total
    FROM Sales 
    WHERE UserID = x
    GROUP BY CAST(JULIANDAY(CreationDate / 1000, 'unixepoch', 'localtime') + d as INT) / 7
    ORDER BY SUM(Amount);
    

答案 1 :(得分:-1)

请尝试执行以下查询:

select 
  min(to_char(to_date(order_date,'mm/dd/yyyy'),'Day'))
    keep(dense_rank first order by sum(sales) desc) best_day,
  min(to_char(to_date(order_date,'mm/dd/yyyy'),'Day'))
    keep(dense_rank last order by sum(sales) desc)worst_day
from orders
where userid=x
group by to_char(to_date(order_date,'mm/dd/yyyy'),'Day');