GVKun编程网logo

tsql – 用于将日期范围转换为每日记录的SQL查询(sql日期转化)

7

对于tsql–用于将日期范围转换为每日记录的SQL查询感兴趣的读者,本文将会是一篇不错的选择,我们将详细介绍sql日期转化,并为您提供关于DATEDIFF()或BETWEEN用于SQL查询中的日期范围

对于tsql – 用于将日期范围转换为每日记录的SQL查询感兴趣的读者,本文将会是一篇不错的选择,我们将详细介绍sql日期转化,并为您提供关于DATEDIFF()或BETWEEN用于SQL查询中的日期范围、mysql – 用于将值列表与任何顺序的字段列表匹配而不重复的SQL查询、Mysql查询在时间戳的日期范围内非常慢、MySQL查询按日期范围分组?的有用信息。

本文目录一览:

tsql – 用于将日期范围转换为每日记录的SQL查询(sql日期转化)

tsql – 用于将日期范围转换为每日记录的SQL查询(sql日期转化)

要求

>我有数据表,可以在日期范围内保存数据.
>允许每条记录与先前的记录重叠(记录具有CreatedOn datetime列).
>新记录可以定义它自己的日期范围,如果它需要可以重叠几个旧记录.
>每个新的重叠记录都会覆盖它重叠的旧记录的设置.

结果集

我需要得到的是每天使用记录重叠的日期范围的数据.它应该返回每天的记录以及该特定日期的相应数据.

要将范围转换为天数,我考虑使用numbers/dates table和用户定义函数(UDF)来获取范围内每一天的数据,但我想知道是否还有其他(如更好*甚至更快)的方式,因为我是使用最新的sql Server 2008 R2.

存储数据

想象一下,我存储的数据看起来像这样

ID | RangeFrom | Rangeto  | Starts | Ends  | CreatedOn (not providing data)
---|-----------|----------|--------|-------|-----------
1  | 20110101  | 20110331 | 07:00  | 15:00
2  | 20110401  | 20110531 | 08:00  | 16:00
3  | 20110301  | 20110430 | 06:00  | 14:00 <- overrides both partially

结果

如果我想从2011年1月1日到2001年5月31日获取数据,结果表应如下所示(省略明显的行):

DayDate | Starts | Ends
--------|--------|------
20110101| 07:00  | 15:00  <- defined by record ID = 1
20110102| 07:00  | 15:00  <- defined by record ID = 1
...                          many rows omitted for obvIoUs reasons
20110301| 06:00  | 14:00  <- defined by record ID = 3
20110302| 06:00  | 14:00  <- defined by record ID = 3
...                          many rows omitted for obvIoUs reasons
20110501| 08:00  | 16:00  <- defined by record ID = 2
20110502| 08:00  | 16:00  <- defined by record ID = 2
...                          many rows omitted for obvIoUs reasons
20110531| 08:00  | 16:00  <- defined by record ID = 2

解决方法

实际上,由于您正在处理日期,因此日历表会更有帮助.
Declare @StartDate date
Declare @EndDate date

;With Calendar As
    (
    Select @StartDate As [Date]
    Union All
    Select DateAdd(d,1,[Date])
    From Calendar
    Where [Date] < @EndDate
    )
Select ...
From Calendar
    Left Join MyTable
        On Calendar.[Date] Between MyTable.Start And MyTable.End
Option ( Maxrecursion 0 );

加成

错过了原帖中关于特朗普规则的部分:

Set DateFormat MDY;
Declare @StartDate date = '20110101';
Declare @EndDate date = '20110501';

-- This first CTE is obvIoUsly to represent
-- the source table
With SampleData As 
    (
    Select 1 As Id,Cast('20110101' As date) As RangeFrom,Cast('20110331' As date) As Rangeto,Cast('07:00' As time) As Starts,Cast('15:00' As time) As Ends,CURRENT_TIMESTAMP As CreatedOn
    Union All Select 2,'20110401','20110531','08:00','16:00',DateAdd(s,CURRENT_TIMESTAMP )
    Union All Select 3,'20110301','20110430','06:00','14:00',2,CURRENT_TIMESTAMP )
    ),Calendar As
    (
    Select @StartDate As [Date]
    Union All
    Select DateAdd(d,[Date])
    From Calendar
    Where [Date] < @EndDate
    ),RankedData As
    (
    Select C.[Date],S.Id,S.RangeFrom,S.Rangeto,S.Starts,S.Ends,Row_Number() Over( Partition By C.[Date] Order By S.CreatedOn Desc ) As Num
    From Calendar As C
        Join SampleData As S
            On C.[Date] Between S.RangeFrom And S.Rangeto
    )
Select [Date],Id,RangeFrom,Rangeto,Starts,Ends
From RankedData
Where Num = 1   
Option ( Maxrecursion 0 );

简而言之,我对所有样本数据进行排名,这些数据优先于同一日期重叠的较新行.

DATEDIFF()或BETWEEN用于SQL查询中的日期范围

DATEDIFF()或BETWEEN用于SQL查询中的日期范围

最近我被告知,BETWEEN在SQL中使用该方法有些不可靠,因此我应该使用DATEDIFF()。但是,另一位程序员告诉我不是这种情况,BETWEEN只要日期格式正确,该方法就可以在所有情况下出色地工作。

请有人通过说明哪种方法更好以及为什么来解决这场辩论。

目前,我的日期范围SQL如下所示:

DATEDIFF(d,'01-Jan-1970',SIH.[Something_Date]) >= 0 AND DATEDIFF(d,'01-Jan-2013',SIH.[Something_Date]) <= 0

但是,如果可以确定它是可靠的,我宁愿这样写:

SIH.[Something_Date] BETWEEN '01-Jan-1970' AND '01-Jan-2013'

在这种情况下,我使用的是MsSQL,但是我已经标记了MySQL,因为我想知道这在这里是否也适用

mysql – 用于将值列表与任何顺序的字段列表匹配而不重复的SQL查询

mysql – 用于将值列表与任何顺序的字段列表匹配而不重复的SQL查询

我最近不得不编写一个查询来过滤一些如下所示的特定数据:

假设我有3个不同的值,我想在我的数据库中的一个表的3个不同字段中搜索,它们必须以所有可能的顺序搜索而不重复.

下面是一个示例(为了便于理解,我将使用命名查询表示法来显示必须放置值的位置):

val1 =“a”,val2 =“b”,val3 =“c”

这是我生成的查询:

SELECT * FROM table WHERE
(fieldA = :val1 AND fieldB = :val2 AND fieldC = :val3) OR
(fieldA = :val1 AND fieldB = :val3 AND fieldC = :val2) OR
(fieldA = :val2 AND fieldB = :val1 AND fieldC = :val3) OR
(fieldA = :val2 AND fieldB = :val3 AND fieldC = :val1) OR
(fieldA = :val3 AND fieldB = :val1 AND fieldC = :val2) OR
(fieldA = :val3 AND fieldB = :val2 AND fieldC = :val1)

我必须做的是生成一个模拟排列而不重复的查询.有没有更好的方法来执行此类查询?

对于3×3来说这是可以的,但如果我需要对9×9之类的更大的东西做同样的事情,那么生成查询将是一个巨大的混乱.

我正在使用MariaDB,但我可以接受可以在Postgresql上运行的答案.
(我想知道是否有一种聪明的方式来编写这种类型的查询而没有“暴力”)

最佳答案
没有更好的方法,但你可以使用:

SELECT *
FROM table
WHERE :val1 in (fieldA,fieldB,fieldC) and
      :val2 in (fieldA,fieldC) and
      :val3 in (fieldA,fieldC)

它至少更短.而且,这是标准的sql,因此它应该适用于任何数据库.

Mysql查询在时间戳的日期范围内非常慢

Mysql查询在时间戳的日期范围内非常慢

mysql表中有一个表,它有大约176万条记录并且还在增长.似乎记录越多,记录就越慢.下面运行一个简单的查询大约需要65秒. Date_run是一个时间戳字段.我想知道是否会让它运行得慢一些.我可以在选项文件中调整任何建议,以使这个宝贝更快?

select *
from stocktrack
where date(date_run) >= '2014-5-22'
and date(date_run) <= '2014-5-29'

> MysqL 5.6版
> Windows 8.1 64位
>英特尔酷睿i7-4770,3.40Ghz 12GB RAM

最佳答案
要提高此查询的性能,请使用合适的索引(将date_run作为索引中的前导列),并在等效谓词中引用“裸列”.

在函数中包装列(如DATE(),就像在查询中一样)会禁用MysqL优化器使用范围扫描操作.通过查询,即使索引可用,每次运行该查询时,MysqL都会对表中的每一行进行完整扫描.

为了提高性能,请在“裸”列上使用谓词,例如:

WHERE date_run >= '2014-5-22' AND date_run <  '2014-5-29' + INTERVAL 1 DAY

(注意,当我们省略日期文字的时间部分时,MysqL假设时间组件为午夜’00:00:00′.我们知道每个日期时间/时间戳值,日期组件等于’2014-05-29’保证不到’2014-05-30’的午夜.)

MysqL需要适当的索引才能对此特定查询使用有效的范围扫描操作.适合此查询的最简单索引是:

... ON stocktrack (date_run) 

(请注意,任何以date_run作为前导列的索引都是合适的.)

使用索引的范围扫描操作(通常)在大型集合上(通常)更有效(和更快),因为MysqL可以非常快速地从考虑中消除大量行.如果没有范围扫描操作,MysqL必须检查表中的每一行.

使用EXPLAIN来比较原始和修改之间的MySQL查询计划.

你问的问题……

“…对选项文件的任何调整……”

该问题的答案实际上取决于您使用的是哪个存储引擎(MyISAM或InnoDB).降压的最大好处来自于分配足够的缓冲区来保存内存中的数据库块,以减少I / O ……但这样做的代价是可以为运行的其他任何内存提供更少的内存,并且过度分配没有任何好处记忆.关于MysqL服务器调优的问题,除了查询性能之外,最好在dba.stackexchange.com上提出.

MySQL查询按日期范围分组?

MySQL查询按日期范围分组?

我在MySQL中有一张表,该表显示了我每天记录的小时数。我正在尝试建立一个视图,该视图将允许我按块/天范围快速将数据分组。最简单的情况是每月一次,这并不难。我可以将日期选择为“%y-%m”,然后按该列分组。

前任:

select time_logged,date_format(start_date,'%Y-%m') AS `month_logged`
from work_log
group by month_logged

如果我按月分组,那很好。但是我的问题是,我需要从每月的13号到下个月的12号进行分组(例如:7月13日至8月12日,8月13日至9月12日,等等)。

有没有一种简单的方法可以在单个查询/视图中执行类似的操作?我似乎无法提出满足我的需求的查询,即使使用不同的日期字段组合也是如此。

今天的关于tsql – 用于将日期范围转换为每日记录的SQL查询sql日期转化的分享已经结束,谢谢您的关注,如果想了解更多关于DATEDIFF()或BETWEEN用于SQL查询中的日期范围、mysql – 用于将值列表与任何顺序的字段列表匹配而不重复的SQL查询、Mysql查询在时间戳的日期范围内非常慢、MySQL查询按日期范围分组?的相关知识,请在本站进行查询。

本文标签: