我问,因为我不确定谷歌的用途 - 对我来说似乎显而易见的尝试没有任何用处。
我在具有特定$值的特定日期时间内进入对象数据库。我希望得到所有销售记录组a)(任何,不只是说"在小时"比如凌晨1点到凌晨4点)3小时的时间范围,b)总计> = $ 1000。
表格如下:
Sales
SaleId int primary key
Item varchar
SaleAmount money
SaleDate datetime
即使只是关于我应该谷歌搜索的建议也会受到赞赏大声笑!
编辑:
在尝试交叉应用解决方案后确定 - 它已经关闭但不完全存在。为了说明,请考虑以下示例数据:
-- table & data script
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Sales](
[pkid] [int] IDENTITY(1,1) NOT NULL,
[item] [int] NULL,
[amount] [money] NULL,
[saledate] [datetime] NULL,
CONSTRAINT [PK_Sales] PRIMARY KEY CLUSTERED
(
[pkid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
INSERT [dbo].[Sales] VALUES (1, 649.3800, CAST(N'2017-12-31T21:46:19.000' AS DateTime))
INSERT [dbo].[Sales] VALUES (1, 830.6700, CAST(N'2018-01-01T08:38:58.000' AS DateTime))
INSERT [dbo].[Sales] VALUES (1, 321.0400, CAST(N'2018-01-01T09:08:04.000' AS DateTime))
INSERT [dbo].[Sales] VALUES (3, 762.0300, CAST(N'2018-01-01T07:26:30.000' AS DateTime))
INSERT [dbo].[Sales] VALUES (2, 733.5100, CAST(N'2017-12-31T12:04:07.000' AS DateTime))
INSERT [dbo].[Sales] VALUES (3, 854.5700, CAST(N'2018-01-01T08:32:11.000' AS DateTime))
INSERT [dbo].[Sales] VALUES (2, 644.1700, CAST(N'2017-12-31T17:49:59.000' AS DateTime))
INSERT [dbo].[Sales] VALUES (1, 304.7700, CAST(N'2018-01-01T08:01:50.000' AS DateTime))
INSERT [dbo].[Sales] VALUES (2, 415.1200, CAST(N'2017-12-31T20:27:28.000' AS DateTime))
INSERT [dbo].[Sales] VALUES (3, 698.1700, CAST(N'2018-01-01T02:39:28.000' AS DateTime))
从评论中简单改编交叉应用解决方案,逐项:
select s.*
, s2.saleamount_sum
from Sales s cross apply
(select sum(s_in.amount) as saleamount_sum
from Sales s_in
where s.item = s_in.item
and s.saledate >= s_in.saledate and s_in.saledate < dateadd(hour, 3, s.saledate)
) s2
where s2.saleamount_sum > 1000
order by s.item, s.saledate
因此实际数据(按项目/时间排序)如下:
pkid item amount saledate
1 1 649.38 2017-12-31 21:46:19.000
8 1 304.77 2018-01-01 08:01:50.000
2 1 830.67 2018-01-01 08:38:58.000
3 1 321.04 2018-01-01 09:08:04.000
5 2 733.51 2017-12-31 12:04:07.000
7 2 644.17 2017-12-31 17:49:59.000
9 2 415.12 2017-12-31 20:27:28.000
10 3 698.17 2018-01-01 02:39:28.000
4 3 762.03 2018-01-01 07:26:30.000
6 3 854.57 2018-01-01 08:32:11.000
和交叉申请方法的结果:
pkid item amount saledate saleamount_sum
2 1 830.67 1/1/18 8:38 AM 1784.82
3 1 321.04 1/1/18 9:08 AM 2105.86
7 2 644.17 12/31/17 5:49 PM 1377.68
9 2 415.12 12/31/17 8:27 PM 1792.8
4 3 762.03 1/1/18 7:26 AM 1460.2
6 3 854.57 1/1/18 8:32 AM 2314.77
通过考虑项目1的方法分析可以看出这个问题。从数据中,我们看到第1项的FIRST销售不参与3小时超过1000美元。然而,第二,第三和第四项第1项销售也参与其中。并且他们被正确挑选出来,pkid = 2和3.但是他们的总和是不对的 - 他们的总和包括第1项的第一次出售,它没有参与时间/金额条件。我原本预计pkid 2的saleamount_sum为1135.44,而pkid 3为1456.48(他们报告的金额减去第一次非参与销售)。
希望这是有道理的。我会尝试摆弄交叉应用查询来获取它。任何能够快速了解我如何获得我所追求的东西的人,请随时加入。
感谢, -sff
答案 0 :(得分:1)
以下是使用apply
的一种方法:
select t.*, tt.saleamount_sum
from t cross apply
(select sum(t2.saleamount) as saleamount_sum
from t t2
where t2.saledate >= t.saledate and t2.saledate < dateadd(hour, 3, t.saledate)
) tt
where tt.saleamount_sum > 1000;
编辑:
如果你想要每个项目(问题中未指定),那么你需要一个条件:
select t.*, tt.saleamount_sum
from t cross apply
(select sum(t2.saleamount) as saleamount_sum
from t t2
where t2.item = t.item and t2.saledate >= t.saledate and t2.saledate < dateadd(hour, 3, t.saledate)
) tt
where tt.saleamount_sum > 1000;
答案 1 :(得分:1)
您的查询有一个错误的比较(s.saledate >= s_in.saledate
)而不是s_in.saledate >= s.saledate
。下面的内部查询查找外部查询的每一行的下一个3小时。
示例数据
DECLARE @Sales TABLE (
[pkid] [int] IDENTITY(1,1) NOT NULL,
[item] [int] NULL,
[amount] [money] NULL,
[saledate] [datetime] NULL
);
INSERT INTO @Sales VALUES (1, 649.3800, CAST(N'2017-12-31T21:46:19.000' AS DateTime))
INSERT INTO @Sales VALUES (1, 830.6700, CAST(N'2018-01-01T08:38:58.000' AS DateTime))
INSERT INTO @Sales VALUES (1, 321.0400, CAST(N'2018-01-01T09:08:04.000' AS DateTime))
INSERT INTO @Sales VALUES (3, 762.0300, CAST(N'2018-01-01T07:26:30.000' AS DateTime))
INSERT INTO @Sales VALUES (2, 733.5100, CAST(N'2017-12-31T12:04:07.000' AS DateTime))
INSERT INTO @Sales VALUES (3, 854.5700, CAST(N'2018-01-01T08:32:11.000' AS DateTime))
INSERT INTO @Sales VALUES (2, 644.1700, CAST(N'2017-12-31T17:49:59.000' AS DateTime))
INSERT INTO @Sales VALUES (1, 304.7700, CAST(N'2018-01-01T08:01:50.000' AS DateTime))
INSERT INTO @Sales VALUES (2, 415.1200, CAST(N'2017-12-31T20:27:28.000' AS DateTime))
INSERT INTO @Sales VALUES (3, 698.1700, CAST(N'2018-01-01T02:39:28.000' AS DateTime))
INSERT INTO @Sales VALUES (4, 600, CAST(N'2018-01-01T02:39:01.000' AS DateTime))
INSERT INTO @Sales VALUES (4, 600, CAST(N'2018-01-01T02:39:02.000' AS DateTime))
INSERT INTO @Sales VALUES (4, 600, CAST(N'2018-01-01T02:39:03.000' AS DateTime))
INSERT INTO @Sales VALUES (4, 600, CAST(N'2018-01-01T02:39:04.000' AS DateTime))
INSERT INTO @Sales VALUES (4, 600, CAST(N'2018-01-01T02:39:05.000' AS DateTime))
INSERT INTO @Sales VALUES (4, 600, CAST(N'2018-01-01T02:39:06.000' AS DateTime))
<强>查询强>
select
s.*
, s2.saleamount_sum
from
@Sales AS s
cross apply
(
select sum(s_in.amount) as saleamount_sum
from @Sales AS s_in
where
s.item = s_in.item
and s_in.saledate >= s.saledate
and s_in.saledate < dateadd(hour, 3, s.saledate)
) AS s2
where s2.saleamount_sum > 1000
order by s.item, s.saledate
;
<强>结果强>
+------+------+--------+-------------------------+----------------+
| pkid | item | amount | saledate | saleamount_sum |
+------+------+--------+-------------------------+----------------+
| 8 | 1 | 304.77 | 2018-01-01 08:01:50.000 | 1456.48 |
| 2 | 1 | 830.67 | 2018-01-01 08:38:58.000 | 1151.71 |
| 7 | 2 | 644.17 | 2017-12-31 17:49:59.000 | 1059.29 |
| 4 | 3 | 762.03 | 2018-01-01 07:26:30.000 | 1616.60 |
| 11 | 4 | 600.00 | 2018-01-01 02:39:01.000 | 3600.00 |
| 12 | 4 | 600.00 | 2018-01-01 02:39:02.000 | 3000.00 |
| 13 | 4 | 600.00 | 2018-01-01 02:39:03.000 | 2400.00 |
| 14 | 4 | 600.00 | 2018-01-01 02:39:04.000 | 1800.00 |
| 15 | 4 | 600.00 | 2018-01-01 02:39:05.000 | 1200.00 |
+------+------+--------+-------------------------+----------------+
我在示例数据中添加了6行item=4
。它们都在3小时内,这6行中有5个子集的总和大于1000.从技术上讲,这个结果是正确的,但你真的想要这种结果吗?
答案 2 :(得分:0)
要在指定的小时间隔内获得所有销售:
SELECT SaleId, sum(SaleAmount) as amount FROM Sales WHERE (HOUR(SaleDate) BETWEEN 1 AND 4) GROUP BY SaleId HAVING amount >=1000;
您可以在WHERE子句中添加其他条件。
答案 3 :(得分:0)
如果你正在寻找0:00-3:00,3:00-6:00这样的时期,你可以按这些时间间隔进行分组。以下查询将小时数舍入为三的倍数,将其与日期和组合在一起:
select format(dt, 'yyyy-mm-dd') + ' ' +
cast(datepart(hour, dt) / 3 * 3 as varchar(2)) as period
, sum(amount) as total
from sales
group by
format(dt, 'yyyy-mm-dd') + ' ' +
cast(datepart(hour, dt) / 3 * 3 as varchar(2))
having sum(amount) > 1000
如果您正在寻找任何3小时的时间段,例如0:33-3:33或12:01-15:01,请参阅Gordon Linoff的回答。