TempTable的聚合函数

时间:2014-08-02 20:06:01

标签: tsql sql-server-2008-r2 aggregate-functions

情景:

我在存储过程中在SQL Server 2008 R2中使用tempTable(#temporary table),我需要使用MIN(), MAX()和...之类的聚合函数来执行一系列计算临时表的列。

但是,临时表没有任何聚合函数。现在这个问题的最佳解决方案是什么?

由于

更新 我想在今天的交易中获得客户银行账户的最低保留

CREATE TABLE #TempTableToday
(
    DetailAccountId     BIGINT,
    RemainToday         BIGINT,
    Profit              DECIMAL(18, 6),
    LastDate            DATETIME
);
CREATE TABLE #TempTableMinRemainToday
(
    DetailAccount2Id     BIGINT,
    MinRemainToday       DECIMAL(18, 2)
);
DECLARE AccountionDocDetailsToday_CURSOR CURSOR  
FOR
    ---------- Get Today Transaction for each Customer's Bank Account ---------
    SELECT   Account.AccountingDocsDetail.Id,
             Account.AccountingDocsDetail.AccountingDocId,
             Account.AccountingDocsDetail.AccountId,
             Account.AccountingDocsDetail.DetailAccountId,
             Account.AccountingDocsDetail.Debit,
             Account.AccountingDocsDetail.Credit,
             Account.AccountingDocsDetail.DateIn
    FROM     Account.AccountingDocsDetail,
             Account.AccountingDocs,
             [Transaction].[Transaction],
             Account.Accounts
    WHERE    Account.AccountingDocsDetail.AccountingDocId = Account.AccountingDocs.Id
        AND  Account.AccountingDocs.Id = [Transaction].[Transaction].AccountingDocId
        AND  Account.AccountingDocsDetail.AccountId = Account.Accounts.Id
        AND  Account.Accounts.Code LIKE '21%'
        AND  Account.AccountingDocsDetail.DateIn = GETDATE()

    OPEN AccountionDocDetailsToday_CURSOR 
      FETCH NEXT FROM AccountionDocDetailsToday_CURSOR INTO @Id,@AccountingDocId,
@AccountId,@DetailAccountId,@Credit,@Debit,@DateAccountindoc
WHILE (@@FETCH_STATUS <> -1)
BEGIN
    DECLARE @lastDateTime DATETIME
    DECLARE @AccNumber NVARCHAR(50)
    DECLARE @BankAccSettingId BIGINT
    DECLARE @Profit DECIMAL(18, 6)
    ----- Customer's Account Number-----
    SELECT   @AccNumber = DetailCode
    FROM     Account.DetailAccount
    WHERE    Id = @DetailAccountId

    SELECT   @BankAccSettingId = BankAccSettingId
    FROM     Account.BankAccount
    WHERE    AccountNumber = @AccNumber

    SELECT   @Profit = ProfitInYear
    FROM     Account.BankAccountSetting
    WHERE    Id = @BankAccSettingId

    SELECT   @RemainToday = dbo.FnCalMandeh(@DetailAccountId, @AccountingDocId)               
    INSERT INTO #TempTableToday
      (
        DetailAccountId,
        RemainToday,
        Profit,
        LastDate
      )
    VALUES
      (
        @DetailAccountId,
        @RemainToday,
        ISNULL(@Profit, 0),
        @DateAccountindoc
      );
    -- I try to obtain: Minimum Remain of Bank Account in today Transactions
    SELECT   @MinRemainToday2 = MIN(#TempTableToday.RemainToday)
    FROM     #TempTableToday
    WHERE    #TempTableToday.DetailAccountId = @DetailAccountId


    INSERT INTO #TempTableMinRemainToday
      (
        DetailAccount2Id,
        MinRemainToday
      )
    VALUES
      (
        @DetailAccountId,
        @MinRemainToday2
      );
    CLOSE AccountionDocDetailsToday_CURSOR
    DEALLOCATE AccountionDocDetailsToday_CURSOR
END

CREATE TABLE #TempTableToday
(
    DetailAccountId     BIGINT,
    RemainToday         BIGINT,
    Profit              DECIMAL(18, 6),
    LastDate            DATETIME
);
CREATE TABLE #TempTableMinRemainToday
(
    DetailAccount2Id     BIGINT,
    MinRemainToday       DECIMAL(18, 2)
);

DECLARE AccountionDocDetailsToday_CURSOR CURSOR  
FOR
    ---------- Get Today Transaction for each Customer's Bank Account ---------
    SELECT   Account.AccountingDocsDetail.Id,
             Account.AccountingDocsDetail.AccountingDocId,
             Account.AccountingDocsDetail.AccountId,
             Account.AccountingDocsDetail.DetailAccountId,
             Account.AccountingDocsDetail.Debit,
             Account.AccountingDocsDetail.Credit,
             Account.AccountingDocsDetail.DateIn
    FROM     Account.AccountingDocsDetail,
             Account.AccountingDocs,
             [Transaction].[Transaction],
             Account.Accounts
    WHERE    Account.AccountingDocsDetail.AccountingDocId = Account.AccountingDocs.Id
        AND  Account.AccountingDocs.Id = [Transaction].[Transaction].AccountingDocId
        AND  Account.AccountingDocsDetail.AccountId = Account.Accounts.Id
        AND  Account.Accounts.Code LIKE '21%'
        AND  Account.AccountingDocsDetail.DateIn = GETDATE()

        OPEN AccountionDocDetailsToday_CURSOR 
          FETCH NEXT FROM AccountionDocDetailsToday_CURSOR INTO @Id,@AccountingDocId,
@AccountId,@DetailAccountId,@Credit,@Debit,@DateAccountindoc
WHILE (@@FETCH_STATUS <> -1)
BEGIN
    DECLARE @lastDateTime DATETIME
    DECLARE @AccNumber NVARCHAR(50)
    DECLARE @BankAccSettingId BIGINT
    DECLARE @Profit DECIMAL(18, 6)
    ----- Customer's Account Number-----
    SELECT   @AccNumber = DetailCode
    FROM     Account.DetailAccount
    WHERE    Id = @DetailAccountId

    SELECT   @BankAccSettingId = BankAccSettingId
    FROM     Account.BankAccount
    WHERE    AccountNumber = @AccNumber

    SELECT   @Profit = ProfitInYear
    FROM     Account.BankAccountSetting
    WHERE    Id = @BankAccSettingId

    SELECT   @RemainToday = dbo.FnCalMandeh(@DetailAccountId, @AccountingDocId)               
    INSERT INTO #TempTableToday
      (
        DetailAccountId,
        RemainToday,
        Profit,
        LastDate
      )
    VALUES
      (
        @DetailAccountId,
        @RemainToday,
        ISNULL(@Profit, 0),
        @DateAccountindoc
      );
    -- I try to obtain: Minimum Remain of Bank Account in today Transactions
    SELECT   @MinRemainToday2 = MIN(#TempTableToday.RemainToday)
    FROM     #TempTableToday
    WHERE    #TempTableToday.DetailAccountId = @DetailAccountId


    INSERT INTO #TempTableMinRemainToday
      (
        DetailAccount2Id,
        MinRemainToday
      )
    VALUES
      (
        @DetailAccountId,
        @MinRemainToday2
      );
    CLOSE AccountionDocDetailsToday_CURSOR
    DEALLOCATE AccountionDocDetailsToday_CURSOR
END

1 个答案:

答案 0 :(得分:1)

请试试这个。我仍然对功能有点不清楚,但我最好的猜测是你在循环中有MIN()所以它只返回一个值。我把它移到循环之外,所以最好的情况是它将检索集合的MIN()。您需要稍微修改此查询以与查询合并。

IF OBJECT_ID(N'tempdb..#AccountingDocsDetail') > 0
    DROP TABLE #AccountingDocsDetail

IF OBJECT_ID(N'tempdb..#TempTableToday') > 0
    DROP TABLE #TempTableToday

IF OBJECT_ID(N'tempdb..#TempTableMinRemainToday') > 0
    DROP TABLE #TempTableMinRemainToday

CREATE TABLE #AccountingDocsDetail
(
    Id                  INT,
    AccountingDocId     INT,
    AccountId           INT,
    DetailAccountId     INT,
    Debit               DECIMAL(18, 6),
    Credit              DECIMAL(18, 6),
    DateIn              DATETIME
)

INSERT INTO #AccountingDocsDetail (Id, AccountingDocId, AccountId, DetailAccountId, Debit, Credit, DateIn)
VALUES
    (1, 2, 1, 1, '100.00', '0.00', '2014-08-03 13:44:32.100'),
    (1, 2, 1, 1, '0.00', '30.00', '2014-08-03 13:46:32.100'),
    (1, 2, 1, 1, '0.00', '30.00', '2014-08-03 13:48:32.100'),
    (1, 2, 1, 1, '0.00', '40.00', '2014-08-03 13:54:32.100'),
    (1, 2, 1, 1, '100.00', '0.00', '2014-08-03 14:44:32.100')

SELECT   *
FROM     #AccountingDocsDetail add1

CREATE TABLE #TempTableToday
(
    DetailAccountId     BIGINT,
    RemainToday         BIGINT,
    Profit              DECIMAL(18, 6),
    LastDate            DATETIME
);
CREATE TABLE #TempTableMinRemainToday
(
    DetailAccount2Id     BIGINT,
    MinRemainToday       DECIMAL(18, 2)
);

DECLARE @AccountingDocId INT
DECLARE @DetailAccountId INT
DECLARE @Debit DECIMAL(18, 6)
DECLARE @Credit DECIMAL(18, 6)
DECLARE @DateAccountindoc DATETIME
DECLARE @StartLoop INT
DECLARE @EndLoop INT
DECLARE @MinRemainToday2 INT


DECLARE @LoopTable TABLE 
        (
            ltId INT IDENTITY(1, 1),
            Id INT,
            AccountingDocId INT,
            AccountId INT,
            DetailAccountId INT,
            Debit DECIMAL(18, 6),
            Credit DECIMAL(18, 6),
            DateIn DATETIME
        )

INSERT INTO @LoopTable
SELECT   ad.Id,
         ad.AccountingDocId,
         ad.AccountId,
         ad.DetailAccountId,
         ad.Debit,
         ad.Credit,
         ad.DateIn
FROM     #AccountingDocsDetail AS ad
         --By casting to date all transactions from 12AM - 12PM is covered
WHERE    CAST(ad.DateIn AS DATE) = CAST(GETDATE() AS DATE)

SELECT   @StartLoop = MIN(lt.ltId),
         @EndLoop = MAX(lt.ltId)
FROM     @LoopTable lt

WHILE @StartLoop <= @EndLoop
BEGIN
    DECLARE @RemainToday INT
    DECLARE @AccNumber NVARCHAR(50)
    DECLARE @BankAccSettingId BIGINT
    DECLARE @Profit DECIMAL(18, 6)

    SELECT   --lt.Id,
             --      lt.AccountingDocId,
             --      lt.AccountId,
             @DetailAccountId = lt.DetailAccountId
             --lt.Debit,
             --lt.Credit,
             --lt.DateIn
    FROM     @LoopTable lt
    WHERE    lt.ltId = @StartLoop

    ----- Customer's Account Number-----
    SELECT   @AccNumber = DetailCode
    FROM     Account.DetailAccount
    WHERE    Id = @DetailAccountId

    SELECT   @BankAccSettingId = BankAccSettingId
    FROM     Account.BankAccount
    WHERE    AccountNumber = @AccNumber

    SELECT   @Profit = ProfitInYear
    FROM     Account.BankAccountSetting
    WHERE    Id = @BankAccSettingId

    SELECT   @RemainToday = dbo.FnCalMandeh(@DetailAccountId, @AccountingDocId)               

    INSERT INTO #TempTableToday (DetailAccountId, RemainToday, Profit, LastDate)
    VALUES (@DetailAccountId, @RemainToday, ISNULL(@Profit, 0), @DateAccountindoc);
    SET @StartLoop = @StartLoop + 1
END   
-- I try to obtain: Minimum Remain of Bank Account in today Transactions
SELECT   @MinRemainToday2 = MIN(ttt.RemainToday)
FROM     #TempTableToday ttt
WHERE    ttt.DetailAccountId = @DetailAccountId

INSERT INTO #TempTableMinRemainToday  (DetailAccount2Id,MinRemainToday)
VALUES  (@DetailAccountId,@MinRemainToday2);

SELECT DetailAccount2Id,MinRemainToday
FROM #TempTableMinRemainToday