获取SQL以逐行处理每一行

时间:2014-01-30 21:46:07

标签: sql sql-server date cursor

我一直在努力试图解决我的问题,我认为它围绕着SQL中的游标,但我不确定。我想我知道如何为单行数据编写循环,但我不知道如何为所有记录运行它:

希望有一个简单的答案:

  1. 我有一张桌子,我们称之为A,有Product_CodeStart_DateEnd_DateValue

    < / LI>
  2. 我需要一个输出表B,其列有Product_CodeMonthYearValue Month * Year介于Start_DateEnd_date

  3. 之间

    A的每条记录都应该创建几条记录到B。希望相当清楚,如果没有,我很乐意详述! :)

1 个答案:

答案 0 :(得分:0)

CREATE TABLE YearMonth(
    Year int not null,
    Month int not null,
    FirstDay date not null,
    LastDay date not null
);

在此表中填写您的数据范围所涵盖的数年和数月(如果您有太多数据,则没有问题)。 您可以使用以下语句执行此操作:

WITH y(year) AS (
    SELECT 2007
    union all
    SELECT 2008
    union all
    SELECT 2009
    union all
    SELECT 2010
    union all
    SELECT 2011
    union all
    SELECT 2012
    union all
    SELECT 2013
    union all
    SELECT 2014
    union all
    SELECT 2015
    union all
    SELECT 2016
),
m(month) AS (
    SELECT 1
    union all
    SELECT 2
    union all
    SELECT 3
    union all
    SELECT 4
    union all
    SELECT 5
    union all
    SELECT 6
    union all
    SELECT 7
    union all
    SELECT 8
    union all
    SELECT 9
    union all
    SELECT 10
    union all
    SELECT 11
    union all
    SELECT 12
)
INSERT INTO YearMonth(Year, Month, FirstDay, LastDay)
SELECT y.year
      ,m.month
      ,convert(date, convert(nvarchar(4), y.year) + '.' + convert(nvarchar(2), m.month) + '.01', 102)
      ,DateAdd(day, - 1,
               CASE WHEN m.month = 12 THEN
                    convert(date, convert(nvarchar(4), y.year + 1) + '.01.01', 102)
                    ELSE
                    convert(date, convert(nvarchar(4), y.year) + '.' + convert(nvarchar(2), m.month + 1) + '.01', 102)
               END)
  FROM y CROSS JOIN m

计算LastDay的棘手部分是这样的:创建一个日期,这是下个月的第一天,然后从中减去一天。这样可以解决月中最后一天可能是28,29,30或31的问题。

然后只使用联接:

INSERT INTO B(Product_Code, Month, Year, Value)
SELECT A.Product_Code
      ,YearMonth.Month
      ,YearMonth.Year
      ,A.Value
  FROM A
       JOIN YearMonth ON YearMonth.LastDay <= A.StartDate
                     AND YearMonth.FirstDay <= A.EndDate

根据“月*年在Start_Date和End_date之间”的确切解释,您可能需要将<=中的一个或两个切换为<