Sql Server:将日历年中的月份转换为会计年度中的月份

时间:2014-03-19 19:16:30

标签: sql sql-server sql-server-2005 calendar

我有一个独特的问题,我根本无法解决这个问题。

所以我在SQL Server 2005中,我可以使用以下数据:

  1. FISCAL_YEAR_START_MONTH INT(会计年度的第一个月)
  2. COUNT_START_MONTH INT(我们需要从
  3. 开始的第一个月)
  4. TOTAL_MONTHS
  5. 年[1-6] _MONTHS - 这是每个日历年的月数
  6. 我需要分配6个财政年度和剩余时间的月份

    例如:

    FISCAL_YEAR_START_MONTH = 7
    COUNT_START_MONTH = 9
    TOTAL_MONTHS = 36
    YEAR1_MONTHS = 4
    YEAR2_MONTHS = 12
    YEAR3_MONTHS = 12
    YEAR4_MONTHS = 8
    

    应输出

    YEAR1_MONTHS YEAR2_MONTHS YEAR3_MONTHS YEAR4_MONTHS YEAR5_MONTHS YEAR6_MONTHS LEFTOVER
    ------------ ------------ ------------ ------------ ------------ ------------ ----------
    10           12           12           2            0            0            0
    

    我只是无法在sql中解决这个问题。很容易看出几个月应该作为一个人在个案中分配,但我无法将其转化为算法。

    我尝试计算每年的日期,并保持我剩下几个月的运行次数,但都没有解决我的问题。

    任何解决方案,即使是上述示例中的特定解决方案(但理想情况下是一般解决方案)也会非常有用!

    编辑:修正了翻转问题,好像我收到了错误的数据

    EDIT2:另一个例子,一个简单的例子:

    FISCAL_YEAR_START_MONTH = 7
    COUNT_START_MONTH = 5
    TOTAL_MONTHS = 14
    YEAR1_MONTHS = 8
    YEAR2_MONTHS = 6
    

    应输出

    YEAR1_MONTHS YEAR2_MONTHS YEAR3_MONTHS YEAR4_MONTHS YEAR5_MONTHS YEAR6_MONTHS LEFTOVER
    ------------ ------------ ------------ ------------ ------------ ------------ ----------
    2           12            0            0            0            0            0
    

3 个答案:

答案 0 :(得分:0)

--Test table.
CREATE TABLE #CalTest (
    ExampleNumber SMALLINT IDENTITY,
    FiscalYearStartMonth SMALLINT,
    CountStartMonth SMALLINT,
    TotalMonths SMALLINT,
    Year1Months SMALLINT,
    Year2Months SMALLINT,
    Year3Months SMALLINT,
    Year4Months SMALLINT,
    Year5Months SMALLINT,
    Year6Months SMALLINT,
    Leftover SMALLINT,
)
GO

--Sample data as per the OP.
INSERT INTO #CalTest (FiscalYearStartMonth, CountStartMonth, TotalMonths, Year1Months, Year2Months, Year3Months, Year4Months, Year5Months, Year6Months, Leftover)
VALUES
    (7,9,36,4,12,12,8,0,0,0),
    (7,5,14,8,6,0,0,0,0,0)
GO

SELECT * FROM #CalTest 
GO

CREATE FUNCTION guest.PickMin
--This function simply picks the smaller of two numbers.
(
    @FirstSmallInt SMALLINT,
    @SecondSmallInt SMALLINT
)
RETURNS SMALLINT
AS
BEGIN
    DECLARE @RetVal SMALLINT

    IF @FirstSmallInt < @SecondSmallInt 
        SET @RetVal = @FirstSmallInt
    ELSE 
        SET @RetVal = @SecondSmallInt

    RETURN @RetVal
END
GO

;WITH CTE AS
(
    --Calculations for Year 1.
    SELECT 
        c.ExampleNumber, c.FiscalYearStartMonth, c.CountStartMonth, 1 AS YearNumber, c.TotalMonths,

        CASE
            WHEN c.CountStartMonth > c.FiscalYearStartMonth THEN
                guest.PickMin( 12 - (c.CountStartMonth - c.FiscalYearStartMonth), c.TotalMonths ) 
            ELSE
                c.FiscalYearStartMonth - c.CountStartMonth
        END AS Year1Months,

        --These are placeholders for Year2 - Year6.
        CAST(NULL AS SMALLINT) AS Year2Months, CAST(NULL AS SMALLINT) AS Year3Months, CAST(NULL AS SMALLINT) AS Year4Months, CAST(NULL AS SMALLINT) AS Year5Months, CAST(NULL AS SMALLINT) AS Year6Months,

        --Calculate the left over months.
        c.TotalMonths - guest.PickMin( 
            CASE
                WHEN c.CountStartMonth > c.FiscalYearStartMonth THEN
                    guest.PickMin( 12 - (c.CountStartMonth - c.FiscalYearStartMonth), c.TotalMonths ) 
                ELSE
                    c.FiscalYearStartMonth - c.CountStartMonth
            END, 
            c.TotalMonths 
            ) AS Leftover
    FROM #CalTest c

    UNION ALL
        --Calculations for Year 2
        SELECT 
        c2.ExampleNumber, c2.FiscalYearStartMonth, c2.CountStartMonth, c2.YearNumber + 1, c2.TotalMonths,
        NULL, guest.PickMin(12, c2.Leftover), NULL, NULL, NULL, NULL,
        c2.Leftover - guest.PickMin( 12, c2.Leftover)
    FROM CTE c2
    WHERE c2.YearNumber = 1

    UNION ALL
        --Calculations for Year 3
        SELECT 
        c2.ExampleNumber, c2.FiscalYearStartMonth, c2.CountStartMonth, c2.YearNumber + 1, c2.TotalMonths,
        NULL, NULL, guest.PickMin(12, c2.Leftover), NULL, NULL, NULL,
        c2.Leftover - guest.PickMin( 12, c2.Leftover)
    FROM CTE c2
    WHERE c2.YearNumber = 2

    UNION ALL
        --Calculations for Year 4
        SELECT 
        c2.ExampleNumber, c2.FiscalYearStartMonth, c2.CountStartMonth, c2.YearNumber + 1, c2.TotalMonths,
        NULL, NULL, NULL, guest.PickMin(12, c2.Leftover), NULL, NULL,
        c2.Leftover - guest.PickMin( 12, c2.Leftover)
    FROM CTE c2
    WHERE c2.YearNumber = 3

    UNION ALL
        --Calculations for Year 5
        SELECT 
        c2.ExampleNumber, c2.FiscalYearStartMonth, c2.CountStartMonth, c2.YearNumber + 1, c2.TotalMonths,
        NULL, NULL, NULL, NULL, guest.PickMin(12, c2.Leftover), NULL,
        c2.Leftover - guest.PickMin( 12, c2.Leftover)
    FROM CTE c2
    WHERE c2.YearNumber = 4

    UNION ALL
        --Calculations for Year 6
        SELECT 
        c2.ExampleNumber, c2.FiscalYearStartMonth, c2.CountStartMonth, c2.YearNumber + 1, c2.TotalMonths,
        NULL, NULL, NULL, NULL, NULL, guest.PickMin(12, c2.Leftover), 
        c2.Leftover - guest.PickMin( 12, c2.Leftover)
    FROM CTE c2
    WHERE c2.YearNumber = 5
)
SELECT 
    --Comment out the next line if you don't want it in your output.
    ExampleNumber, FiscalYearStartMonth, CountStartMonth, TotalMonths,

    --These are the output columns the OP asked for.
    --SUM() will exclude the NULL values used as placeholders in the above CTE.
    SUM(Year1Months) Year1Months,
    SUM(Year2Months) Year2Months,
    SUM(Year3Months) Year3Months,
    SUM(Year4Months) Year4Months,
    SUM(Year5Months) Year5Months,
    SUM(Year6Months) Year6Months,
    MIN(Leftover) Leftover
FROM CTE
GROUP BY ExampleNumber, FiscalYearStartMonth, CountStartMonth, TotalMonths
ORDER BY ExampleNumber

--Drop as needed.
DROP FUNCTION guest.PickMin
GO

答案 1 :(得分:0)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct pgm {
    int rows;
    int cols;
    int **pixels;
} pgmPic; 

void dataCreate(pgmPic *);
void trailCreate(pgmPic *);
pgmPic *blaze(pgmPic *, char*);

int main(int argc, char** argv){
    printf("Hi\n");
    if(argc != 3){
        printf("Improper use of arguments.\n");
        return 0;
    }
    int row, col;
    printf("point 0");
    FILE *data = fopen(argv[1], "r");
    printf("point 1");
    fscanf(data, "%d\n%d\n", &row, &col);
    printf("point 2");
    pgmPic *myPic = (pgmPic *) malloc(sizeof(pgmPic));
    myPic->pixels = (int**) malloc(sizeof(int)* myPic->rows);
    for(int a = 0; a < myPic->rows; a++)
        myPic->pixels[a] = (int*) malloc(sizeof(int) * myPic->cols);
    printf("point 3");
    int elev[row][col];
    for(int w = 0; w < row; w++){
        for(int v = 0; v < col; v++){
            fscanf(data, "%d", &elev[w][v]);
        }
    }
    printf("point 4");
    int min = elev[0][0];
    int max = elev[0][0];
    for(int x = 0; x < row; x++){
        for(int y = 0; y < col; y++){
            if(elev[x][y] < min)
                min = elev[x][y];
            if(elev[x][y] > max)
                max = elev[x][y];
        }
    }
    printf("point 5");
    double multiplier = (max-min)/200;
    for(int w = 0; w < row; w++){
        for(int v = 0; v < col; v++){
            elev[w][v] = elev[w][v] - min;
            elev[w][v] = elev[w][v] * multiplier;
            myPic->pixels[w][v] = 255 - elev[w][v];
        }
    }
    printf("point 6");
    myPic->rows = row;
    myPic->cols = col;
    printf("point 7");
    dataCreate(myPic);
    printf("point 8");
    myPic = blaze(myPic, argv[2]);
    printf("point 9");
    trailCreate(myPic);
    return 0;
}

void dataCreate(pgmPic *pic){
    FILE *myfile = fopen("data.pgm", "w");
    fprintf(myfile, "P2\n");
    fprintf(myfile, "%d %d\n", pic->cols, pic->rows);
    for(int i = 0; i < pic->rows; i++){
        for(int j = 0; j < pic->cols; j++){
            fprintf(myfile, "%3d ", pic->pixels[pic->rows][pic->cols]);
        }
        fprintf(myfile, "\n");
    }
    fclose(myfile);
} 

void trailCreate(pgmPic *pic){
    FILE *myfile = fopen("data-trail.pgm", "w");
    fprintf(myfile, "P2\n");
    fprintf(myfile, "%d %d\n", pic->cols, pic->rows);
    for(int i = 0; i < pic->rows; i++){
        for(int j = 0; j < pic->cols; j++){
            fprintf(myfile, "%3d ", pic->pixels[pic->rows][pic->cols]);
        }
        fprintf(myfile, "\n");
    } 
    fclose(myfile);
}

pgmPic *blaze(pgmPic *pic, char* dir){
    pgmPic *thing = pic;
    int row, col;
    if(strcmp(dir, "W-E") == 0){
        row = pic->rows / 2;
        col = 0;
        while(col < pic->cols){
            thing->pixels[row][col] = 0;
            col++;
            if(thing->pixels[row-1][col] <= thing->pixels[row][col] && thing->pixels[row][col] >= thing->pixels[row+1][col])
                continue;
            if(thing->pixels[row-1][col] >= thing->pixels[row][col] && thing->pixels[row-1][col] >= thing->pixels[row+1][col]){
                row--;
                continue;
            }
            if(thing->pixels[row-1][col] <= thing->pixels[row+1][col] && thing->pixels[row][col] <= thing->pixels[row+1][col]){
                row++;
                continue;
            }
        }
    }
    if(strcmp(dir, "E-W") == 0){
        row = pic->rows / 2;
        col = pic->cols - 1;
        while(col > 0){
            thing->pixels[row][col] = 0;
            col--;
            if(thing->pixels[row-1][col] <= thing->pixels[row][col] && thing->pixels[row][col] >= thing->pixels[row+1][col])
                continue;
            if(thing->pixels[row-1][col] <= thing->pixels[row+1][col] && thing->pixels[row][col] <= thing->pixels[row+1][col]){
                row++;
                continue;
            }
            if(thing->pixels[row-1][col] >= thing->pixels[row][col] && thing->pixels[row-1][col] >= thing->pixels[row+1][col]){
                row--;
                continue;
            }
        }
    }
    if(strcmp(dir, "S-N") == 0){
        col = pic->cols / 2;
        row = pic->rows - 1;
        while(col > 0){
            thing->pixels[row][col] = 0;
            row--;
            if(thing->pixels[row][col-1] <= thing->pixels[row][col] && thing->pixels[row][col] >= thing->pixels[row][col+1])
                continue;
            if(thing->pixels[row][col-1] >= thing->pixels[row][col] && thing->pixels[row][col-1] >= thing->pixels[row][col+1]){
                row--;
                continue;
            }
            if(thing->pixels[row][col-1] <= thing->pixels[row][col+1] && thing->pixels[row][col] <= thing->pixels[row][col+1]){
                row++;
                continue;
            }
        }
    }
    if(strcmp(dir, "N-S") == 0){
        col = pic->cols / 2;
        row = 0;
        while(col < pic->cols){
            thing->pixels[row][col] = 0;
            row++;
            if(thing->pixels[row][col-1] <= thing->pixels[row][col] && thing->pixels[row][col] >= thing->pixels[row][col+1])
                continue;
            if(thing->pixels[row][col-1] <= thing->pixels[row][col+1] && thing->pixels[row][col] <= thing->pixels[row][col+1]){
                col++;
                continue;
            }
            if(thing->pixels[row][col-1] >= thing->pixels[row][col] && thing->pixels[row][col-1] >= thing->pixels[row][col+1]){
                col--;
                continue;
            }
        }
    }
    return thing;
}

答案 2 :(得分:-1)

Select 1 sn, DATENAME(mm,Getdate())+', '+ convert(Varchar(50),Year(Getdate())) Display, DateAdd(mm,DateDiff(mm,0,getdate())-0,0) [From], dateadd(day, 0 - day(dateadd(month, 1 , getdate())), dateadd(month, 1 , getdate())) [To]

Union

Select 2 sn, DATENAME(mm,dateadd (mm, -1,getdate()))+', '+ convert(Varchar(50), Year(dateadd (mm, -1,getdate()))) Display, DateAdd(mm,DateDiff(mm,0,dateadd (mm, -1,getdate()))-0,0) [From], dateadd(day, 0 - day(dateadd(month, 1 ,dateadd (mm, -1,getdate()))), dateadd(month, 1 ,dateadd (mm, -1,getdate()))) [To]

Union

Select 3 sn, DATENAME(mm,dateadd (mm, -1,dateadd (mm, -1,getdate())))+', '+ convert(Varchar(50), Year(dateadd (mm, -1,dateadd (mm, -1,getdate())))) Display, DateAdd(mm,DateDiff(mm,0,dateadd (mm, -1,dateadd (mm, -1,getdate())))-0,0) [From], dateadd(day, 0 - day(dateadd(month, 1 ,dateadd (mm, -1,dateadd (mm, -1,getdate())))), dateadd(month, 1 ,dateadd (mm, -1,dateadd (mm, -1,getdate())))) [To]

Union
/* ---- Continu ---------------------- */

Select 11 sn, DATENAME(mm,dateadd (mm, -1,dateadd (mm, -9,getdate())))+', '+ convert(Varchar(50), Year(dateadd (mm, -1,dateadd (mm, -9,getdate())))) Display, DateAdd(mm,DateDiff(mm,0,dateadd (mm, -1,dateadd (mm, -9,getdate())))-0,0) [From], dateadd(day, 0 - day(dateadd(month, 1 ,dateadd (mm, -1,dateadd (mm, -9,getdate())))), dateadd(month, 1 ,dateadd (mm, -1,dateadd (mm, -9,getdate())))) [To] 

Union 

Select 12 sn, DATENAME(mm,dateadd (mm, -1,dateadd (mm, -10,getdate())))+', '+ convert(Varchar(50), Year(dateadd (mm, -1,dateadd (mm, -10,getdate())))) Display, DateAdd(mm,DateDiff(mm,0,dateadd (mm, -1,dateadd (mm, -10,getdate())))-0,0) [From], dateadd(day, 0 - day(dateadd(month, 1 ,dateadd (mm, -1,dateadd (mm, -10,getdate())))), dateadd(month, 1 ,dateadd (mm, -1,dateadd (mm, -10,getdate())))) [To] Order By sn