查询销售额,按周分组
Querying sales, grouped by weeks
我正在尝试在 SQLLite 中为我的应用组合一个查询,想寻求一点帮助。
我要写的查询:
“我是用户 ID x 的用户。对于我的个人工作周,可以在我想要的任何一天 D 开始(周日到周六,周一到周日等),我想看看哪一天就销售额而言,工作周是我最差的一周,但也是我最好的一周。
为简单起见,"worst" 和 "best" 仅表示该周最高和最低销售额的总和。
如果每个人的工作周都从周日开始,这很容易,但事实并非如此。我必须克服 SQL 挑战,将数据库中的所有行分组 table 不仅按周,而且按自定义周(用户定义一周的开始和结束日期)。
例如,如果我的工作周从星期日开始,那么在过去的一周中,5 月 28 日那一周是星期日,并且是我工作周的开始(到 6 月 3 日这个星期六结束)。我将对 table.
中的所有记录遵循此模式
但是,不同的用户可以让他们的工作周从 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' 的正确值偏移量?它现在似乎正在工作。我看到模式变成了 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
请尝试执行以下查询:
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');
你们很亲近。
您正在将 d
添加到日期时间。我不知道这是否真的增加了天数。如果在 SQLite 中将整数添加到日期时间,我无法弄清楚会发生什么。要保存它,请将这一天添加到儒略日。您不必先获取日期时间,顺便说一句,从这个儒略日开始,您可以一步完成:
julianday(CreationDate / 1000, 'unixepoch', 'localtime') + d
这是我在您的查询中看到的唯一真正的缺陷。
儒略日是小数,例如 2457907.5。当您调用带有 /
的除法时,您会得到一个小数结果。我看到您将此结果转换为 INT
,但我建议先转换为 INT,然后再进行除法,这样会隐含地成为整数除法。
cast(julianday(CreationDate / 1000, 'unixepoch', 'localtime') + d as int) / 7
这只是为了便于阅读;我得到一个天数(2457907 而不是某个小数点 2457907.5)和整数除以 7(例如 2457907 / 7 = 351129)。
整个查询:
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_date
和 till_date
并不总是代表完整的 7 天,而是只代表工作日(例如从周日到周六的一周,但只在周一、周三和周五工作,它将显示星期一和星期五的日期)。显示真实的一周需要做更多的工作。 (我现在最好不要尝试这个,因为很容易请假一天,而无法尝试查询。)
编辑: 这是我对每周开始和结束日期的尝试。当我们对浮点值调用 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);
我正在尝试在 SQLLite 中为我的应用组合一个查询,想寻求一点帮助。
我要写的查询:
“我是用户 ID x 的用户。对于我的个人工作周,可以在我想要的任何一天 D 开始(周日到周六,周一到周日等),我想看看哪一天就销售额而言,工作周是我最差的一周,但也是我最好的一周。
为简单起见,"worst" 和 "best" 仅表示该周最高和最低销售额的总和。
如果每个人的工作周都从周日开始,这很容易,但事实并非如此。我必须克服 SQL 挑战,将数据库中的所有行分组 table 不仅按周,而且按自定义周(用户定义一周的开始和结束日期)。
例如,如果我的工作周从星期日开始,那么在过去的一周中,5 月 28 日那一周是星期日,并且是我工作周的开始(到 6 月 3 日这个星期六结束)。我将对 table.
中的所有记录遵循此模式但是,不同的用户可以让他们的工作周从 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' 的正确值偏移量?它现在似乎正在工作。我看到模式变成了 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
请尝试执行以下查询:
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');
你们很亲近。
您正在将
d
添加到日期时间。我不知道这是否真的增加了天数。如果在 SQLite 中将整数添加到日期时间,我无法弄清楚会发生什么。要保存它,请将这一天添加到儒略日。您不必先获取日期时间,顺便说一句,从这个儒略日开始,您可以一步完成:julianday(CreationDate / 1000, 'unixepoch', 'localtime') + d
这是我在您的查询中看到的唯一真正的缺陷。
儒略日是小数,例如 2457907.5。当您调用带有
/
的除法时,您会得到一个小数结果。我看到您将此结果转换为INT
,但我建议先转换为 INT,然后再进行除法,这样会隐含地成为整数除法。cast(julianday(CreationDate / 1000, 'unixepoch', 'localtime') + d as int) / 7
这只是为了便于阅读;我得到一个天数(2457907 而不是某个小数点 2457907.5)和整数除以 7(例如 2457907 / 7 = 351129)。
整个查询:
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_date
和 till_date
并不总是代表完整的 7 天,而是只代表工作日(例如从周日到周六的一周,但只在周一、周三和周五工作,它将显示星期一和星期五的日期)。显示真实的一周需要做更多的工作。 (我现在最好不要尝试这个,因为很容易请假一天,而无法尝试查询。)
编辑: 这是我对每周开始和结束日期的尝试。当我们对浮点值调用 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);