SQL无法使用RIGHT JOIN提供预期结果

时间:2014-06-18 14:53:47

标签: sql sql-server right-join

我一直在处理这个问题已经有一段时间了,并在right join问题之后阅读了right join问题,但是我无法弄明白这一点。

我有以下查询:

DECLARE @ExpectedDateSample VARCHAR(10)
DECLARE @Date datetime
DECLARE @DaysInMonth INT
DECLARE @i INT

--GIVE VALUES
SET @ExpectedDateSample = SUBSTRING(CONVERT(VARCHAR, DATEADD(MONTH, +0, GETDATE()), 112),5,2)+'/'+CONVERT(VARCHAR(4), DATEPART(YEAR, GETDATE()))
SET @Date = Getdate()
SELECT @DaysInMonth = datepart(dd,dateadd(dd,-1,dateadd(mm,1,cast(cast(year(@Date) as varchar)+'-'+cast(month(@Date) as varchar)+'-01' as datetime))))
SET @i = 1

--MAKE TEMP TABLE
CREATE TABLE #TempDays
(
    [days] VARCHAR(50)
)

WHILE @i <= @DaysInMonth
BEGIN
    INSERT INTO #TempDays
    VALUES(@i)
    SET @i = @i + 1
END



SELECT DATEPART(DD, CONVERT(DATE, a.budg_tempDODate1, 103)) ExpectedDate, SUM(a.budg_do1_total) ExpectedAmount
FROM CRM.dbo.budget a
RIGHT JOIN #TempDays on DATEPART(DD, CONVERT(DATE, a.budg_tempDODate1, 103)) = #TempDays.days
WHERE DATEPART(MONTH, a.budg_tempDODate1) = DATEPART(MONTH, GetDate()) AND DATEPART(YEAR, a.budg_tempDODate1) = DATEPART(YEAR, GetDate())
GROUP BY a.budg_tempDODate1

--DROP TABLE TO ALLOW CREATION AGAIN    
DROP TABLE #TempDays

在我的Budget table中,我有几天失踪,但这就是为什么我创建一个Temp表来计算一个月的所有日子。然后右键加入Temp表。

我想计算一个月中每天的预计现金数量。如果我的预算表中不存在该日期,则不要将其完全排除,而是显示为0。

我目前正在获得

+------+---------------+
| DAYS |    AMOUNT     |
+------+---------------+
|    1 | 34627.000000  |
|    2 | 72474.000000  |
|    3 | 27084.000000  |
|    4 | 9268.000000   |
|    5 | 32304.000000  |
|    6 | 23261.000000  |
|    7 | 5614.000000   |
|    9 | 3464.000000   |
|   10 | 20046.000000  |
|   12 | 7449.000000   |
|   13 | 265163.000000 |
|   14 | 24210.000000  |
|   15 | 68848.000000  |
|   16 | 31702.000000  |
|   17 | 2500.000000   |
|   19 | 2914.000000   |
|   20 | 238406.000000 |
|   21 | 15642.000000  |
|   22 | 2514.000000   |
|   23 | 46521.000000  |
|   24 | 34093.000000  |
|   25 | 899081.000000 |
|   26 | 204085.000000 |
|   27 | 316341.000000 |
|   28 | 48826.000000  |
|   29 | 2657.000000   |
|   30 | 440401.000000 |
+------+---------------+

我期待的是:

+------+---------------+
| DAYS |    AMOUNT     |
+------+---------------+
|    1 | 34627.000000  |
|    2 | 72474.000000  |
|    3 | 27084.000000  |
|    4 | 9268.000000   |
|    5 | 32304.000000  |
|    6 | 23261.000000  |
|    7 | 5614.000000   |
|    8 | NULL          |
|    9 | 3464.000000   |
|   10 | 20046.000000  |
|   11 | NULL          |
|   12 | 7449.000000   |
|   13 | 265163.000000 |
|   14 | 24210.000000  |
|   15 | 68848.000000  |
|   16 | 31702.000000  |
|   17 | 2500.000000   |
|   18 | NULL          |
|   19 | 2914.000000   |
|   20 | 238406.000000 |
|   21 | 15642.000000  |
|   22 | 2514.000000   |
|   23 | 46521.000000  |
|   24 | 34093.000000  |
|   25 | 899081.000000 |
|   26 | 204085.000000 |
|   27 | 316341.000000 |
|   28 | 48826.000000  |
|   29 | 2657.000000   |
|   30 | 440401.000000 |
+------+---------------+

正如您所看到的,预期结果仍显示我不期待任何价值的日子。 任何人都可以注意到我的查询有任何错误...任何帮助和提示将不胜感激。

我正在使用SQL Server 2008

谢谢! 迈克

3 个答案:

答案 0 :(得分:2)

将您的where子句更改为部分加入,并显示#tempdays的日期值,而不是数据表

SELECT      
    #TempDays.days ExpectedDate, SUM(a.budg_do1_total) ExpectedAmount
FROM CRM.dbo.budget a
RIGHT JOIN #TempDays on 
    DATEPART(DD, CONVERT(DATE, a.budg_tempDODate1, 103)) = #TempDays.days
    AND DATEPART(MONTH, a.budg_tempDODate1) = DATEPART(MONTH, GetDate()) 
    AND DATEPART(YEAR, a.budg_tempDODate1) = DATEPART(YEAR, GetDate())
GROUP BY #TempDays.days

答案 1 :(得分:0)

问题是你的Where子句 -

  

在哪里DATEPART(月,a.budg_tempDODate1)= DATEPART(月,GetDate())和DATEPART(年,a.budg_tempDODate1)= DATEPART(年,GetDate())

答案 2 :(得分:0)

where子句和group by子句应用于具有较少数据的表。 因此,结果集被限制在表中,而忽略join子句的数据更少。

我已经重写并测试了它。

declare @budget table 
(
    budg_tempDODate1 datetime,
    budg_do1_total float
)

insert into @budget(budg_tempDODate1, budg_do1_total)
select '2014-06-01', 25
union select '2014-06-01', 23
union select '2014-06-02', 23
union select '2014-06-02', 23
union select '2014-06-02', 23
union select '2014-06-03', 23
union select '2014-06-04', 23
union select '2014-06-05', 23
union select '2014-06-05', 23
union select '2014-06-05', 23
union select '2014-06-06', 23
union select '2014-06-07', 23
union select '2014-06-08', 23
union select '2014-06-09', 23
union select '2014-06-10', 23

DECLARE @ExpectedDateSample VARCHAR(10)
DECLARE @Date datetime
DECLARE @DaysInMonth INT
DECLARE @i INT

--GIVE VALUES
SET @ExpectedDateSample = SUBSTRING(CONVERT(VARCHAR, DATEADD(MONTH, +0, GETDATE()), 112),5,2)+'/'+CONVERT(VARCHAR(4), DATEPART(YEAR, GETDATE()))
SET @Date = Getdate()
SELECT @DaysInMonth = datepart(dd,dateadd(dd,-1,dateadd(mm,1,cast(cast(year(@Date) as varchar)+'-'+cast(month(@Date) as varchar)+'-01' as datetime))))
SET @i = 1

--MAKE TEMP TABLE
CREATE TABLE #TempDays
(
    [days] int
)

WHILE @i <= @DaysInMonth
BEGIN
    INSERT INTO #TempDays
    VALUES(@i)
    SET @i = @i + 1
END

--select * from #TempDays

SELECT 
    td.days as ExpectedDate, 
    SUM(isnull(a.budg_do1_total, 0)) ExpectedAmount
FROM 
    --CRM.dbo.budget a
    #TempDays td
    left outer JOIN @budget a on 
        DATEPART(MONTH, a.budg_tempDODate1) = DATEPART(MONTH, GetDate()) 
        AND DATEPART(YEAR, a.budg_tempDODate1) = DATEPART(YEAR, GetDate())
        AND DATEPART(DD, CONVERT(DATE, a.budg_tempDODate1, 103)) = td.days
GROUP BY 
    --a.budg_tempDODate1
    td.days

--DROP TABLE TO ALLOW CREATION AGAIN    
DROP TABLE #TempDays

以下是sql fiddle