我有一个问题:
SELECT
d.FiscalMonth,
d.FiscalMonthOfYear,
p.Name
FROM
DimDate d
LEFT JOIN FactSales f on f.SaleDate=d.PKDate
LEFT JOIN DimPerson p on p.PersonId=f.PersonId
WHERE d.FiscalYear='2014/7/1'
group by d.FiscalMonth, d.FiscalMonthOfYear, p.Name
ORDER BY d.FiscalMonthOfYear asc, p.PersonID asc
这给了我这些结果:
哪个都没关系,我想包括所有月份,甚至是那些没有数据的月份。 (在本例中为FiscalMonth 2-12。)
我遇到的问题是有一个NULL值,我有数据,IE。 FiscalMonthOfYear 1.红色框。
我如何才能为FiscalMonth = 2014-07-01返回那个“NULL”?我尝试过各种各样的where子句,但是当我从结果中删除“NULL”值时,我也删除了我想要的所有(IE.FiscalMonthOfYear 2-12)
非常感谢任何帮助或指导!
谢谢! -Russ
更新:
DimDate表有主键PKDate,每个日期都是一行:
DimDate
PKDate ....
2014-07-01
2014-07-02
2014-07-03
etc.
FaceSales表在给定的一天中有一个或多个销售交易:
FactSales
SaleDate Amount
2014-07-01 34.99
2014-07-01 21.89
2014-07-02 24.77
2014-07-04 22.77
问题是FactSales可能在某一天没有销售。所以我的查询是找到没有交易的一天(或多天),并且由于LEFT JOIN正在返回它。我如何去除这个结果,因为它不在我的结果中?
SELECT
d.PKDate
,f.SaleDate
FROM
DimDate d
LEFT JOIN FactSales f on f.SaleDate=d.PKDate
LEFT JOIN DimPerson p on p.PersonId=f.PersonId
WHERE d.FiscalYear='2014/7/1'
ORDER BY d.PKDate
答案 0 :(得分:1)
问题源于你实际上是在尝试同时做两件事:
正如在这些情况下经常发生的那样......你应该解决两个不同的问题然后把结果放在一起(在这种特定情况下使用UNION)。
这样的事情:
SELECT * FROM
(
SELECT DISTINCT
d.FiscalMonth,
d.FiscalMonthOfYear,
p.Name
FROM DimDate d
JOIN FactSales f ON f.SaleDate=d.PKDate
JOIN DimPerson p ON p.PersonId=f.PersonId
WHERE d.FiscalYear='2014/7/1'
) UNION (
SELECT
d.FiscalMonth,
d.FiscalMonthOfYear,
NULL AS Name
FROM DimDate d
LEFT JOIN FactSales f ON f.SaleDate=d.PKDate
WHERE d.FiscalYear='2014/7/1'
GROUP BY d.FiscalMonth, d.FiscalMonthOfYear, p.Name
HAVING COUNT(f.SaleDate)=0
)
ORDER BY FiscalMonthOfYear asc, PersonID ASC
我还没有测试过,可能有更好的方法可以解决第二部分(SUBSELECT,EXISTS),但这取决于您使用的引擎。
答案 1 :(得分:0)
您可以按如下方式进行内部联接:
SELECT
d.FiscalMonth,
d.FiscalMonthOfYear,
p.Name
FROM
DimDate d
INNER JOIN FactSales f on f.SaleDate=d.PKDate
LEFT JOIN DimPerson p on p.PersonId=f.PersonId
WHERE d.FiscalYear='2014/7/1'
group by d.FiscalMonth, d.FiscalMonthOfYear, p.Name
ORDER BY d.FiscalMonthOfYear asc, p.PersonID asc
内连接执行两个表的并集,而不优先使用左表。有关联接的更多信息,请阅读此博客:Visual representation of sql joins
其中声明INNER JOIN
将返回左表(表A)中右表中具有匹配记录的所有记录(表B)以及LEFT JOIN
将返回左表(表A)中的所有记录,无论这些记录中的任何记录是否与右表(表B)匹配