VerySource

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 1489|回复: 13

帮忙看看这一SQL语句,该怎么写?表里有5W多条数据,怎么查询才能速度快。

[复制链接]

1

主题

4

帖子

4.00

积分

新手上路

Rank: 1

积分
4.00
发表于 2020-3-13 19:00:01 | 显示全部楼层 |阅读模式
产品名          时间          数量          单价
----------  ---------------   ---------    ----------
   A           2016-11-01        20            15
   A           2016-11-08        40            15
   A           2016-11-28        70            14.5
   A           2016-12-01        10            14.5
   A           2016-12-15        80            14.8
   A           2016-12-25        55            14.8  

查询日期在2016-12-01到2016-12-31时间段内数据。
统计出某产品在某个时间段内不同价格的数量是多少?并且需要找到查询起始时间前的最后一次使用的价格是多少。

结果
产品名       时间          数量     单价     单价2      差价
-------    ---------     ------- ---------  ----------  -------
   A       2016-12-01     10       14.5       14.5        0
   A       2016-12-25     135      14.8       14.5        0.3
回复

使用道具 举报

0

主题

28

帖子

25.00

积分

新手上路

Rank: 1

积分
25.00
发表于 2020-6-10 20:30:01 | 显示全部楼层
没有看明白什么意思 数量 10 和135 是怎么来的

回复

使用道具 举报

0

主题

211

帖子

108.00

积分

新手上路

Rank: 1

积分
108.00
发表于 2020-6-11 13:45:01 | 显示全部楼层
select ID=identity(int, 1, 1), 产品名, 时间=max(时间), 数量=sum(数量), 单价 into #T from T
where 时间 between '2016-12-01' and '2016-12-31'
group by 产品名, 单价
order by 时间

select *,单价2=isnull( (select 单价 from #T where ID=A.ID-1), 单价), 差价=单价-isnull( (select 单价 from #T where ID=A.ID-1), 单价) from #T A
回复

使用道具 举报

0

主题

211

帖子

108.00

积分

新手上路

Rank: 1

积分
108.00
发表于 2020-6-11 14:30:01 | 显示全部楼层
create table T(产品名 char(1), 时间 datetime, 数量 int, 单价 decimal(10,1))
insert T select   'A',           '2016-11-01',        20,            15
union all select    'A',           '2016-11-08',        40,            15
union all select    'A',           '2016-11-28',        70,            14.5
union all select    'A',           '2016-12-01',        10,            14.5
union all select    'A',           '2016-12-15',        80,            14.8
union all select    'A',           '2016-12-25',        55,            14.8

select ID=identity(int, 1, 1), 产品名, 时间=max(时间), 数量=sum(数量), 单价 into #T from T
where 时间 between '2016-12-01' and '2016-12-31'
group by 产品名, 单价
order by 时间

select *,单价2=isnull( (select 单价 from #T where ID=A.ID-1), 单价), 差价=单价-isnull( (select 单价 from #T where ID=A.ID-1), 单价) from #T A

--result
ID          产品名  时间                                                     数量          单价           单价2          差价            
----------- ---- ------------------------------------------------------ ----------- ------------ ------------ -------------
1           A    2016-12-01 00:00:00.000                                10          14.5         14.5         .0
2           A    2016-12-25 00:00:00.000                                135         14.8         14.5         .3

(2 row(s) affected)
回复

使用道具 举报

1

主题

4

帖子

4.00

积分

新手上路

Rank: 1

积分
4.00
 楼主| 发表于 2020-6-11 17:30:01 | 显示全部楼层
数量10:日期在2016-12-01到2016-12-31之间,并且价格为14.5的数量之和。
数量135:日期在2016-12-01到2016-12-31之间,并且价格为14.8的数量之和。
日期为最后一次执行价格的日期。
回复

使用道具 举报

0

主题

126

帖子

73.00

积分

新手上路

Rank: 1

积分
73.00
发表于 2020-6-11 19:15:01 | 显示全部楼层
select A.产品名,MAX(A.时间) AS 时间,SUM(A.数量) AS 数量,A.单价 AS 单价1,B.单价 AS 单价2,A.单价-B.单价 AS 差价
FROM testtb A LEFT JOIN testtb B ON A.产品名=B.产品名
AND B.时间=(SELECT MAX(时间) FROM testtb WHERE 产品名=A.产品名 AND 时间<A.时间 AND (单价<>A.单价 OR 时间<'2016-12-01'))
WHERE A.时间>='2016-12-01' AND A.时间<='2016-12-31'
GROUP BY A.产品名,A.单价,B.单价
回复

使用道具 举报

0

主题

126

帖子

73.00

积分

新手上路

Rank: 1

积分
73.00
发表于 2020-6-11 20:00:01 | 显示全部楼层
create table testtb(
产品名 char(1),
时间    char(10),
数量    int,
单价    numeric(12,2)
)
go

insert into testtb(产品名,时间,数量,单价)
SELECT 'A','2016-11-01', 20,15
UNION ALL SELECT 'A','2016-11-08',40,5
UNION ALL SELECT 'A','2016-11-28',70,14.5
UNION ALL SELECT 'A','2016-12-01',10,14.5
UNION ALL SELECT 'A','2016-12-15',80,14.8
UNION ALL SELECT 'A','2016-12-25',55,14.8
GO

select A.产品名,MAX(A.时间) AS 时间,SUM(A.数量) AS 数量,A.单价 AS 单价1,B.单价 AS 单价2,A.单价-B.单价 AS 差价
FROM testtb A LEFT JOIN testtb B ON A.产品名=B.产品名
AND B.时间=(SELECT MAX(时间) FROM testtb WHERE 产品名=A.产品名 AND 时间<A.时间 AND (单价<>A.单价 OR 时间<'2016-12-01'))
WHERE A.时间>='2016-12-01' AND A.时间<='2016-12-31'
GROUP BY A.产品名,A.单价,B.单价
回复

使用道具 举报

1

主题

4

帖子

4.00

积分

新手上路

Rank: 1

积分
4.00
 楼主| 发表于 2020-6-11 23:00:01 | 显示全部楼层
单价2:显示的是,日期2016-11-28所对应的价格14.5
回复

使用道具 举报

0

主题

126

帖子

73.00

积分

新手上路

Rank: 1

积分
73.00
发表于 2020-6-11 23:45:01 | 显示全部楼层
产品名  时间         数量          单价1                                     单价2                                     差价
--------------------------------------- ---------------------------------------
A    2016-12-01 10          14.50                                   14.50                                   0.00
A    2016-12-25 135         14.80                                   14.50                                   0.30
回复

使用道具 举报

0

主题

49

帖子

35.00

积分

新手上路

Rank: 1

积分
35.00
发表于 2020-6-12 10:30:01 | 显示全部楼层
--环境
create table tab
(
产品名 varchar(2),
时间 varchar(10),
数量 int,
单价 decimal(8,2)
)

insert into tab select    'A',           '2016-11-01',        20,            15
insert into tab select    'A',           '2016-11-08',        40,            15
insert into tab select    'A',           '2016-11-28',        70,            14.5
insert into tab select    'A',           '2016-12-01',        10,            14.5
insert into tab select    'A',           '2016-12-15',        80,            14.8
insert into tab select    'A',           '2016-12-25',        55,            14.8  

--语句
select *,差价 = 单价 - 单价2 from
(
select 产品名,max(时间) as 时间,sum(数量) as 数量,单价,
单价2 = (select top 1 单价 from tab where 产品名 = a.产品名 and 时间 < '2016-12-01' order by 时间 desc)
from tab a
where 时间 between  '2016-12-01' and '2016-12-31'
group by 产品名,单价
)tt

--结果
产品名  时间         数量          单价         单价2        差价         
---- ---------- ----------- ---------- ---------- -----------
A    2016-12-01 10          14.50      14.50      .00
A    2016-12-25 135         14.80      14.50      .30

(所影响的行数为 2 行)

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|CopyRight © 2008-2023|verysource.com ( 京ICP备17048824号-1 )

快速回复 返回顶部 返回列表