基于最大生产日期和最小生产日期MTD、WTD、YTD SQL Server的总和

基于最大生产日期和最小生产日期MTD、WTD、YTD SQL Server的总和,sql,sql-server,query-help,Sql,Sql Server,Query Help,您好,我正在尝试创建一个自动查询,显示月到日期、年到日期和周到日期,并为每个月创建一列。如果生产日期是存款的最大-最小生产日期总和,我需要合计余额金额。这将给我一个YTD专栏。如果有人有任何想法的话,我还需要做每月到目前为止和每周到目前为止的工作。在此方面的任何帮助都将不胜感激。谢谢 另外,我正在使用microsoft sql server management studio 以下是我到目前为止的情况: select SUM([curr_bal_amt]) as total_amt , [pro

您好,我正在尝试创建一个自动查询,显示月到日期、年到日期和周到日期,并为每个月创建一列。如果生产日期是存款的最大-最小生产日期总和,我需要合计余额金额。这将给我一个YTD专栏。如果有人有任何想法的话,我还需要做每月到目前为止和每周到目前为止的工作。在此方面的任何帮助都将不胜感激。谢谢

另外,我正在使用microsoft sql server management studio 以下是我到目前为止的情况:

select SUM([curr_bal_amt]) as total_amt , [prod_dt] as date123
from [dbo].[DEPOSIT_TEST]
group by [prod_dt];
这将生成如下图表:

总的来说,我需要计算一年到目前为止,减去我的最大日期减去我的最小日期。稍后,当我导入更多数据时,我需要执行mtd和wtd。谢谢

编辑:我希望使用我当前的表格,所以编辑这个表格可能会有帮助,因为我忘了提到我有3天的数据间隔

-此外,对于我的prod_dt列,如果prod_dt相同,我必须对多个余额求和。是否有一个简单的查询,只需减去最近日期的货币余额总和-上个月的货币余额总和的第一个日期。谢谢你的帮助,肖恩,非常感谢


如果你能使用我专栏的名字,那将非常有益于我更好地学习。非常感谢。我的表名为Deposit_Test,列名与图片中的列名相同。再次感谢

这会让你很好地了解如何计算这些总数。我不知道您在表中还需要哪些其他数据,但您应该能够修改下面的查询以获取这些数据

MS SQL Server 2017架构设置

/********************************CALENDAR********************************/
/* 
  My original answer made use of a Calendar Table, but I realized it 
  was overkill for this situation. I still think every database should
  have both a Calendar Table and a Numbers Table. They are both very 
  useful. I use the ct here just to populate my test table, but I've 
  left some very basic creation to show you how it can be done. Calcs 
  done here allow your final query to JOIN to it and avoid RBAR to be 
  more set-based, and save a lot of processing for large tables.  
  NOTE: This original date table concept is from Aaron Bertrand.
*/

CREATE TABLE datedim (
      theDate           date        PRIMARY KEY
    , theDay            AS DATEPART(day, theDate)           --int
    , theWeek           AS DATEPART(week, theDate)          --int 
    , theMonth          AS DATEPART(month, theDate)         --int
    , theYear           AS DATEPART(year, theDate)          --int
    , yyyymmdd          AS CONVERT(char(8), theDate, 112)   /* yyyymmdd */
);

/************************************************************************/
/* 
  Use the catalog views to generate as many rows as we need. This example
  creates a date dimension for all of 2018.
*/
INSERT INTO datedim ( theDate ) 
SELECT d
FROM (
    SELECT d = DATEADD(day, rn - 1, '20180101')
    FROM 
    (
        SELECT TOP (DATEDIFF(day, '20180101', '20190101')) 
            rn = ROW_NUMBER() OVER (ORDER BY s1.object_id)
        FROM sys.all_objects AS s1
        CROSS JOIN sys.all_objects AS s2
        ORDER BY s1.object_id
    ) AS x
) AS y;
/************************************************************************/

/***** TEST TABLE SETUP *****/
CREATE TABLE t1 ( id int identity, entryDate date, cnt int) ;

INSERT INTO t1 (entryDate, cnt)
SELECT theDate, 2
FROM datedim
;

/* Remove a few "random" records to test our counts. */
DELETE FROM t1 
WHERE datePart(day,entryDate) IN (10,6,14,22) OR datepart(month,entryDate) = 6
;
/* Make sure the first day or our week is consistent. */
SET DATEFIRST 7 ; /* SUNDAY */ 

/* Then build out our query needs with CTEs. */
; WITH theDate AS (
  SELECT d.dt FROM ( VALUES ( '2018-05-17' ) ) d(dt) 
)
, base AS (
  SELECT t1.entryDate
    , t1.cnt
    , theDate.dt
    , datepart(year,theDate.dt) AS theYear
    , datepart(month,theDate.dt) AS theMonth
    , datepart(week,theDate.dt) AS theWeek
  FROM t1
  CROSS APPLY theDate
  WHERE t1.EntryDate <= theDate.dt
    AND datePart(year,t1.EntryDate) = datePart(year,theDate.dt)
)
/* Year-to-date totals */
, ytd AS ( 
  SELECT b.theYear, sum(cnt) AS s
  FROM base b
  GROUP BY b.theYear
)
/* Month-to-date totals */
, mtd AS (
  SELECT b2.theYear, b2.theMonth, sum(cnt) AS s
  FROM base b2
  WHERE b2.theMonth = datePart(month,b2.EntryDate)
  GROUP BY b2.theYear, b2.theMonth
)
/* Week-to-date totals */
, wtd AS (
  SELECT b3.theYear, b3.theMonth, sum(cnt) AS s
  FROM base b3
  WHERE b3.theWeek = datePart(week,b3.EntryDate)
  GROUP BY b3.theYear, b3.theMonth
)
SELECT blah = 'CountRow'
  , ytd.s AS ytdAmt
  , mtd.s AS mtdAmt
  , wtd.s AS wtdAmt
FROM ytd 
CROSS APPLY mtd
CROSS APPLY wtd 
|     blah | ytdAmt | mtdAmt | wtdAmt |
|----------|--------|--------|--------|
| CountRow |    236 |     28 |      8 |
主查询

/********************************CALENDAR********************************/
/* 
  My original answer made use of a Calendar Table, but I realized it 
  was overkill for this situation. I still think every database should
  have both a Calendar Table and a Numbers Table. They are both very 
  useful. I use the ct here just to populate my test table, but I've 
  left some very basic creation to show you how it can be done. Calcs 
  done here allow your final query to JOIN to it and avoid RBAR to be 
  more set-based, and save a lot of processing for large tables.  
  NOTE: This original date table concept is from Aaron Bertrand.
*/

CREATE TABLE datedim (
      theDate           date        PRIMARY KEY
    , theDay            AS DATEPART(day, theDate)           --int
    , theWeek           AS DATEPART(week, theDate)          --int 
    , theMonth          AS DATEPART(month, theDate)         --int
    , theYear           AS DATEPART(year, theDate)          --int
    , yyyymmdd          AS CONVERT(char(8), theDate, 112)   /* yyyymmdd */
);

/************************************************************************/
/* 
  Use the catalog views to generate as many rows as we need. This example
  creates a date dimension for all of 2018.
*/
INSERT INTO datedim ( theDate ) 
SELECT d
FROM (
    SELECT d = DATEADD(day, rn - 1, '20180101')
    FROM 
    (
        SELECT TOP (DATEDIFF(day, '20180101', '20190101')) 
            rn = ROW_NUMBER() OVER (ORDER BY s1.object_id)
        FROM sys.all_objects AS s1
        CROSS JOIN sys.all_objects AS s2
        ORDER BY s1.object_id
    ) AS x
) AS y;
/************************************************************************/

/***** TEST TABLE SETUP *****/
CREATE TABLE t1 ( id int identity, entryDate date, cnt int) ;

INSERT INTO t1 (entryDate, cnt)
SELECT theDate, 2
FROM datedim
;

/* Remove a few "random" records to test our counts. */
DELETE FROM t1 
WHERE datePart(day,entryDate) IN (10,6,14,22) OR datepart(month,entryDate) = 6
;
/* Make sure the first day or our week is consistent. */
SET DATEFIRST 7 ; /* SUNDAY */ 

/* Then build out our query needs with CTEs. */
; WITH theDate AS (
  SELECT d.dt FROM ( VALUES ( '2018-05-17' ) ) d(dt) 
)
, base AS (
  SELECT t1.entryDate
    , t1.cnt
    , theDate.dt
    , datepart(year,theDate.dt) AS theYear
    , datepart(month,theDate.dt) AS theMonth
    , datepart(week,theDate.dt) AS theWeek
  FROM t1
  CROSS APPLY theDate
  WHERE t1.EntryDate <= theDate.dt
    AND datePart(year,t1.EntryDate) = datePart(year,theDate.dt)
)
/* Year-to-date totals */
, ytd AS ( 
  SELECT b.theYear, sum(cnt) AS s
  FROM base b
  GROUP BY b.theYear
)
/* Month-to-date totals */
, mtd AS (
  SELECT b2.theYear, b2.theMonth, sum(cnt) AS s
  FROM base b2
  WHERE b2.theMonth = datePart(month,b2.EntryDate)
  GROUP BY b2.theYear, b2.theMonth
)
/* Week-to-date totals */
, wtd AS (
  SELECT b3.theYear, b3.theMonth, sum(cnt) AS s
  FROM base b3
  WHERE b3.theWeek = datePart(week,b3.EntryDate)
  GROUP BY b3.theYear, b3.theMonth
)
SELECT blah = 'CountRow'
  , ytd.s AS ytdAmt
  , mtd.s AS mtdAmt
  , wtd.s AS wtdAmt
FROM ytd 
CROSS APPLY mtd
CROSS APPLY wtd 
|     blah | ytdAmt | mtdAmt | wtdAmt |
|----------|--------|--------|--------|
| CountRow |    236 |     28 |      8 |

同样,您需要获取的数据可能会改变整个查询,但这应该指向正确的方向。您可以使用每个CTE来验证YTD、MTD和WTD总计。

日历表会有所帮助。您好,欢迎使用SO。要做到这一点,您需要使用聚合函数,如SUM。如果你想要一些实际的帮助,你需要提供一些实际的细节。如果您可以尝试一下,并提供上面的查询,以及其他详细信息,如所需结果数据的明确示例,这将非常有帮助。在提问之前,请学习如何提问。如果没有表格结构、样本输入、预期输出,您希望我们如何帮助您?????根据给出的信息,我们能给出的最佳答案是将日期按月、周、年进行划分。