1

ああ、私はこれを取得していません。

DynamicsGPのアカウントのテーブルが7列あります。特定の月にアクティビティがなかったアカウントの空白の月を入力する必要があります。

次のような行を持つメモリ内テーブル@MONTHSを作成しました。

アカウント、説明、年、月、月の名前、Netchange、PeriodBal


1110000、NULL、2006、1、NULL、0、NULL

これは、DynamicsGPからの同じ情報と一致する必要があります。GPからの同様の行は次のようになります。

1110000、Petty Cash、2006、1、1月、15.00、343.97

2月に小額の現金を使わなかった場合、2006年2月にはそのアカウントの行はありません。空の月が埋められるように、@MONTHSテーブルをDynamicsGPテーブルと右結合にします。

読みやすくするために短縮されたSQLは次のとおりです。

SELECT Z.GPACCOUNTNO, 
Z.DESCRIPTION, 
Z.FISCALYEAR, 
Z.FISCALPERIOD, 
Z.FISCALPERIODNAME, 
Z.NETCHANGE, 
Z.PERIODBALANCE
FROM Z
RIGHT JOIN @MONTHS M 
    ON Z.GPACCOUNTNO = M.GPACCOUNTNO
    AND Z.FISCALPERIOD = M.FISCALPERIOD
    AND Z.FISCALYEAR = M.FISCALYEAR 

SQLは永久に実行されます。(つまり、忍耐力を失う5分前)

@MONTHSテーブルが意図したとおりに表示されることを確認しました。2つのテーブルで「UNIONALL」を実行してみましたが、重複しています。

テーブルZに特定のアカウント/年/月の現在の行がない場合は、@MONTHSテーブルにその行をNetchange残高0で追加する必要があります。

ご協力ありがとうございました。完全なSQLは以下のとおりです。


/* Create in memory table to hold account numbers */
DECLARE @i int
DECLARE @c int
DECLARE @ACCT char(129)
DECLARE @numrows int
DECLARE @numyears int
DECLARE @y int
DECLARE @m int
DECLARE @ACCT_TABLE TABLE (
idx smallint Primary Key IDENTITY(1,1),
account char(129)
)

/* Populate account number table */
INSERT @ACCT_TABLE
select distinct ACTNUMST from SBM01.[dbo].[GL00105]

/* Year table reads available years in the DB */
DECLARE @YEAR_TABLE TABLE (
idx smallint Primary Key IDENTITY(1,1),
YEAR1 smallint
)

/* Populate year table */
INSERT @YEAR_TABLE
SELECT distinct YEAR1 FROM SBM01.dbo.SY40101 ORDER BY YEAR1

/* Create our table of months to UNION to the main accounts */
DECLARE @MONTHS table (
GPACCOUNTNO char(129),
DESCRIPTION char(51),
FISCALYEAR smallint ,
FISCALPERIOD smallint,
FISCALPERIODNAME char(21),
NETCHANGE numeric(19, 5),
PERIODBALANCE numeric(19, 5)
)

/* Here comes the heavy lifting. 
We loop over the account numbers and add year and month values.
*/
SET @i = 1
SET @numrows = (SELECT COUNT(*) FROM @ACCT_TABLE)
IF @numrows > 0
WHILE(@i <= (SELECT MAX(idx) FROM @ACCT_TABLE))
BEGIN

/* Get the next account number */
SET @ACCT = (SELECT account FROM @ACCT_TABLE WHERE idx = @i)
SET @c = 1
SET @numyears = (SELECT COUNT(*) FROM @YEAR_TABLE)
    WHILE(@c <= (SELECT MAX(idx) FROM @YEAR_TABLE))
    BEGIN
        SET @y = (SELECT YEAR1 FROM @YEAR_TABLE WHERE idx = @c)
        SET @m = '0'
            WHILE(@m < '13')
            BEGIN
                INSERT INTO @MONTHS (GPACCOUNTNO, DESCRIPTION, FISCALPERIOD, FISCALYEAR, FISCALPERIODNAME, NETCHANGE, PERIODBALANCE)
                VALUES (@ACCT, NULL, @m, @y, NULL, '0', NULL)
                SET @m = @m + 1
            END
            SET @c = @c + 1
        END
        SET @i = @i + 1
    END
/* We should now have a populated Database */   

SELECT Z.GPACCOUNTNO, Z.DESCRIPTION, Z.FISCALYEAR, Z.FISCALPERIOD, Z.FISCALPERIODNAME, Z.NETCHANGE, Z.PERIODBALANCE
FROM    ( SELECT    RTRIM(B.[ACTNUMST]) AS GPACCOUNTNO,
                RTRIM(C.[ACTDESCR]) AS DESCRIPTION,
                A.[YEAR1] AS FISCALYEAR,
                A.[PERIODID] AS FISCALPERIOD,
                E.[PERNAME] AS FISCALPERIODNAME,
                ISNULL(A.[PERDBLNC], 0) AS NETCHANGE,
                ( SELECT    ISNULL(SUM(D.[PERDBLNC]), 0)
                  FROM      SBM01.[dbo].[GL10110] D
                  WHERE     D.[ACTINDX] = A.[ACTINDX]
                            AND D.[YEAR1] = A.[YEAR1]
                            AND D.[PERIODID] <= A.[PERIODID]
                ) AS PERIODBALANCE
      FROM      SBM01.[dbo].[GL10110] A
                INNER JOIN SBM01.[dbo].[GL00105] B ON B.[ACTINDX] = A.[ACTINDX]
                INNER JOIN SBM01.[dbo].[GL00100] C ON C.[ACTINDX] = A.[ACTINDX]
                INNER JOIN SBM01.[dbo].[SY40100] E ON E.[YEAR1] = A.[YEAR1]
                                                AND E.[PERIODID] = A.[PERIODID]
                                                AND E.[SERIES] = 0
      UNION ALL
      SELECT    RTRIM(B.[ACTNUMST]) AS GPACCOUNTNO,
                RTRIM(C.[ACTDESCR]) AS DESCRIPTION,
                A.[YEAR1] AS FISCALYEAR,
                A.[PERIODID] AS FISCALPERIOD,
                E.[PERNAME] AS FISCALPERIODNAME,
                ISNULL(A.[PERDBLNC], 0) AS NETCHANGE,
                ( SELECT    ISNULL(SUM(D.[PERDBLNC]), 0)
                  FROM      SBM01.[dbo].[GL10111] D
                  WHERE     D.[ACTINDX] = A.[ACTINDX]
                            AND D.[YEAR1] = A.[YEAR1]
                            AND D.[PERIODID] <= A.[PERIODID]
                ) AS PERIODBALANCE
      FROM      SBM01.[dbo].[GL10111] A
                INNER JOIN SBM01.[dbo].[GL00105] B ON B.[ACTINDX] = A.[ACTINDX]
                INNER JOIN SBM01.[dbo].[GL00100] C ON C.[ACTINDX] = A.[ACTINDX]
                INNER JOIN SBM01.[dbo].[SY40100] E ON E.[YEAR1] = A.[YEAR1]
                                                AND E.[PERIODID] = A.[PERIODID]
                                                AND E.[SERIES] = 0
) Z
RIGHT JOIN @MONTHS M 
    ON Z.GPACCOUNTNO = M.GPACCOUNTNO
    AND Z.FISCALPERIOD = M.FISCALPERIOD
    AND Z.FISCALYEAR = M.FISCALYEAR 
ORDER BY Z.[GPACCOUNTNO],
     M.[FISCALYEAR],
     M.[FISCALPERIOD]
4

2 に答える 2

1

@Months テーブルを開始点として使用して (必要な月がすべて提供されているため)、利用可能な場合は Z からの値を入力してみませんか?

SELECT 
M.GPACCOUNTNO, 
M.DESCRIPTION, 
M.FISCALYEAR, 
M.FISCALPERIOD, 
M.FISCALPERIODNAME, 
ISNULL(Z.NETCHANGE, 0) as NETCHANGE
ISNULL(Z.PERIODBALANCE, 0) as PERIODBALANCE
FROM @MONTHS M
LEFT JOIN Z
    ON Z.GPACCOUNTNO = M.GPACCOUNTNO
    AND Z.FISCALPERIOD = M.FISCALPERIOD
    AND Z.FISCALYEAR = M.FISCALYEAR 
于 2012-08-22T14:04:33.210 に答える
1

SQL case ステートメントを使用して、null の場合に結合できます

CREATE TABLE #TMP
(
    id int,
    [month] datetime
)
INSERT INTO #TMP(id,[month])values(1,GETDATE())
INSERT INTO #TMP(id,[month])values(2,null)
INSERT INTO #TMP(id,[month])values(3,GETDATE())
INSERT INTO #TMP(id,[month])values(4,GETDATE())

CREATE TABLE #TMP2
(
    id int,
    [month] datetime
)
INSERT INTO #TMP2(id,[month])values(1,GETDATE())
INSERT INTO #TMP2(id,[month])values(2,GETDATE())
INSERT INTO #TMP2(id,[month])values(3,GETDATE())
INSERT INTO #TMP2(id,[month])values(4,GETDATE())

select * from #TMP
select * from #TMP2


SELECT #TMP.[id], case when #TMP.[month] is null then #TMP2.[month] else #TMP.month end
from #tmp
inner join #tmp2 on #tmp.id= #tmp2.id

drop table #tmp,#tmp2
于 2012-08-22T14:03:17.567 に答える