Arrrgh,我没有得到这个。
我有一张Dynamics GP的帐户表,其中有7列。对于某个月没有任何活动的帐户,我需要填写空白月份。
我创建了一个内存表@MONTHS,其行如下:
帐户,说明,年份,月份,月份名称,Netchange,PeriodBal
1110000,NULL,2006,1,NULL,0,NULL
这应该与来自Dynamics GP的相同信息相匹配。 GP的类似行似乎如下:
1110000,Petty Cash,2006,1,January,15.00,343.97
如果我们在2月没有花费任何小额现金,那么在2006年2月就没有该帐户的行,我想用DynamicsGP表制作@MONTHS表RIGHT JOIN,以便填补空白月份。
这是为缩短可读性而缩短的缩写:
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表看起来像我打算。我已经尝试用两个表做一个“UNION ALL”,它给了我重复。
如果表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]
答案 0 :(得分:1)
您可以在null
时使用SQL case语句进行连接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
答案 1 :(得分: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