Sql 为什么赢了';这个查询不能正常工作吗?

Sql 为什么赢了';这个查询不能正常工作吗?,sql,sql-server,left-join,right-join,Sql,Sql Server,Left Join,Right Join,我的MasterSales表如下所示 SalesDate | Category | Total ----------------------------- 1/1/2000 01 100 1/1/2000 02 110 1/2/2000 01 80 1/2/2000 03 20 我的Category表如下所示 SalesDate | Category | Total --------------

我的
MasterSales
表如下所示

SalesDate | Category | Total
----------------------------- 
1/1/2000    01          100 
1/1/2000    02          110
1/2/2000    01          80
1/2/2000    03          20
我的
Category
表如下所示

SalesDate | Category | Total
----------------------------- 
1/1/2000    01          100 
1/1/2000    02          110
1/2/2000    01          80
1/2/2000    03          20
我的查询如下所示:

SELECT m.SalesDate, c.Name, SUM(ISNULL(m.Total,0)) AS TotalSales
FROM MasterSales m
LEFT JOIN Category c ON c.ID = m.Category
WHERE m.SalesDate BETWEEN '1/1/2000' AND '1/2/2000'
SalesDate | Name | TotalSales
------------------------------
1/1/2000    A      100
1/1/2000    B      110
1/1/2000    C      0
1/1/2000    D      0
1/2/2000    A      80
1/2/2000    B      0
1/2/2000    C      20
1/2/2000    D      0
我想要的结果如下:

SELECT m.SalesDate, c.Name, SUM(ISNULL(m.Total,0)) AS TotalSales
FROM MasterSales m
LEFT JOIN Category c ON c.ID = m.Category
WHERE m.SalesDate BETWEEN '1/1/2000' AND '1/2/2000'
SalesDate | Name | TotalSales
------------------------------
1/1/2000    A      100
1/1/2000    B      110
1/1/2000    C      0
1/1/2000    D      0
1/2/2000    A      80
1/2/2000    B      0
1/2/2000    C      20
1/2/2000    D      0
但我得到的结果是:

SalesDate | Name | TotalSales
------------------------------
1/1/2000    A      100
1/1/2000    B      110
1/2/2000    A      80
1/2/2000    C      20
我已经尝试使用
RIGHT JOIN
而不是
LEFT JOIN
,并在
FROM
子句上切换表,但结果仍然相同。有人能帮我解释一下为什么它不能正常工作吗

注意:我正在使用SQLServer2005(如果有必要的话)

在条件之间添加日期

我相信有更好的方法可以做到这一点


欢呼声

已更新:更改了使用

我建议您创建一个加法表

;WITH control_table AS (
      SELECT DISTINCT SalesDate, Name
        FROM MasterSales ms
             CROSS JOIN Category c
       )

SELECT d.SalesDate,
       c.name,
       COALESCE(sum(m.total),0) totalsales
  FROM control_table d
       LEFT OUTER JOIN Category c
            ON d.Name = c.name
       LEFT OUTER JOIN MasterSales m
            ON (c.id = m.category
                AND d.SalesDate = m.salesdate)
WHERE d.SalesDate BETWEEN '1/1/2000' 
                      AND '1/2/2000'
GROUP BY 
       d.SalesDate,
       c.name
ORDER BY 
       d.SalesDate,
       c.name;

试试这个。这涵盖您拥有MasterSales的所有日期。换句话说,这将填补当天缺少的类别。但是,如果要填写缺失的日期,则需要创建一个日期控制表。。查看日期表的

;with control_table as (
  select distinct SalesDate, ID
  from MasterSales ms
  cross join Category c
  where ms.SalesDate between '1/1/2000' AND '1/2/2000'
  )


select ct.SalesDate, c.Name as Category, coalesce(sum(ms.Total),0) as Total
from control_table ct
inner join Category c
  on ct.ID = c.ID
left join MasterSales ms
  on ct.SalesDate = ms.SalesDate
  and ct.ID = ms.Category
group by ct.SalesDate, c.Name
order by ct.SalesDate asc, c.Name asc

这是我的答案

WITH MasterSales (SalesDate, Category, Total) AS (
  SELECT       '1/1/2000','01',100
  UNION SELECT '1/1/2000','02',110
  UNION SELECT '1/2/2000','01',80
  UNION SELECT '1/2/2000','03',20
), Category (ID, Name) AS (
  SELECT       '01','A'
  UNION SELECT '02','B'
  UNION SELECT '03','C'
  UNION SELECT '04','D'
), getDates AS (
  SELECT DISTINCT SalesDate 
  FROM MasterSales 
  WHERE SalesDate BETWEEN '1/1/2000' AND '1/2/2000'
)

SELECT gD.SalesDate, C.Name, SUM(ISNULL(MS.Total,0)) AS TotalSales
FROM getDates AS gD
CROSS JOIN Category AS C
LEFT JOIN MasterSales AS MS 
    ON MS.Category = C.ID
    AND MS.SalesDate = gD.SalesDate 
GROUP BY gD.SalesDate, C.Name

最后,你的问题解决了。使用此查询:

SELECT AAA.SalesDate,AAA.Name,ISNULL(BBB.TotalSales,0) as TotalSales  
FROM (
    (SELECT m.SalesDate, c.Name
    FROM MasterSales m,Category c
    WHERE m.SalesDate BETWEEN '1/1/2000' AND '1/2/2000'
    GROUP BY m.SalesDate,c.Name) AAA

    LEFT JOIN 

    (SELECT m.SalesDate,c.Name, SUM(ISNULL(m.Total,0)) AS TotalSales
    FROM MasterSales m,Category c
    WHERE m.SalesDate BETWEEN '1/1/2000' AND '1/2/2000'
    AND c.ID=m.Category 
    GROUP BY m.SalesDate,c.Name) BBB 
    on AAA.SalesDate=BBB.SalesDate AND AAA.Name=BBB.Name) 
说明:

查询的第一部分(AAA)选择
saledate
Category
的所有组合

查询的第二部分(BBB)选择
saledate
Category
TotalSales

然后我们在
saledate
Category
加入这两个网站(AAA和BBB)


很好用!!!。请参阅。

在查询的末尾添加
分组依据m.SalesDate,c.Name
,这里的逻辑是什么?您如何获得类别D的销售日期为01012000和01022000?您加入了条件
c.ID=m.Category
,因此显然
Name=D
不会被选中,因为
ID=4
在另一个类别中不可用table@TinTran例如我也试过了,但结果是一样的@SatheeshVariath Variath:我在查询@Gone时使用了
Between
:我想通过使用
left-join-Category
将显示来自
Category
的所有数据,即使在另一个表中没有匹配?顺便问一下,我如何在评论中添加特征线?非常感谢所有试图帮助我的人。我选择Darka的答案是因为它是在ManagementStudio上最容易尝试的答案,而且它工作得非常完美(并不是说其他人都错了,我只是没有全部尝试):为什么是否定的?你试过了吗(创建另一个表并将所有数据插入其中?我不认为这是一个好主意。这几乎比我的好-你忘了
SUM
@Alexander,谢谢,SUM补充道,我不认为这对所有这些静态值有什么好处,在这里你看到的是静态的??这只是cte的示例而已;)我怀疑这将失去我或sam yi解决方案的性能