我有一个包含3个表的SQL数据库:
Customer record
表,保存主数据(每行是唯一的)Customer notes
,每个笔记数据/时间戳(每个客户可能有很多笔记,或根本没有笔记) Product
表,显示哪位客户购买了哪种产品
表:tbl_Customer_Records
客户ID ----公司名称-----公司分部-----促销代码
表:tbl_Customer_Notes
CustomerID ----注意-----创建日期
表:tbl_Customer_Products
客户ID ----产品类别
我想要的是提取仅包含最新笔记的客户记录列表,因此如果存在多个笔记,则没有重复的行。但是,如果没有备注存在,我还希望我的报告包含客户记录。我已经使用SELECT MAX函数实现了第一部分,并且效果很好,问题是当我在下面的最后一行代码中添加OR = NULL子句时。这不起作用,我无法找到解决方案。
任何建议都将不胜感激!
SELECT
[tbl_Customer_Records].[CustomerID],
[tbl_Customer_Records].[Company Name],
[tbl_Customer_Records].[Company Segment],
[tbl_Customer_Records].[Promo Code],
[tbl_Customer_Notes].[Note],
[tbl_Customer_Products].[Product Category]
FROM
tbl_Customer_Records
LEFT OUTER JOIN tbl_Customer_Notes
ON tbl_Customer_Records.CustomerID = tbl_Customer_Notes.CustomerID
LEFT OUTER JOIN tbl_Customer_Products
ON tbl_Customer_Records.CustomerID = tbl_Customer_Products.CustomerID
WHERE
[Product Category] in ('Nuts','Bolts','Screws','Spanners')
AND
[Created Date] in (SELECT MAX ([Created Date]) FROM tbl.Customer_Notes GROUP BY [CustomerID])
OR tbl_Customer_Note.Note is null
答案 0 :(得分:1)
您可以在ON
谓词中添加过滤条件,以保留左表中的行,并从第一个LEFT OUTER JOIN运算符中仅从右表中获取所需的匹配行。以下查询应该有效:
SELECT
CR.[CustomerID],
CR.[Company_Name],
CR.[Company_Segment],
CR.[Promo_Code],
CN.[Note],
CP.[Product_Category]
FROM
tbl_Customer_Records CR
LEFT OUTER JOIN tbl_Customer_Notes CN
ON CR.CustomerID = CN.CustomerID AND CN.[Created_Date] in (SELECT MAX ([Created_Date])
FROM tbl_Customer_Notes
WHERE CR.CustomerID = tbl_Customer_Notes.CustomerID
GROUP BY [CustomerID])
LEFT OUTER JOIN tbl_Customer_Products CP
ON CR.CustomerID = CP.CustomerID
WHERE
[Product_Category] in ('Nuts','Bolts','Screws','Spanners')
答案 1 :(得分:1)
应该有效,尝试使用NULL值:
SELECT a.[CustomerID],
a.[Company Name],
a.[Company Segment],
a.[Promo Code],
a.[Note],
a.[Product Category]
FROM (
SELECT
cr.[CustomerID],
cr.[Company Name],
cr.[Company Segment],
cr.[Promo Code],
cn.[Note],
cp.[Product Category],
ROW_NUMBER() OVER(PARTITION BY cr.[CustomerID] ORDER BY cn.[Created Date] DESC) as rnk
FROM tbl_Customer_Records cr
LEFT JOIN tbl_Customer_Notes cn
ON cr.CustomerID = cn.CustomerID
LEFT JOIN tbl_Customer_Products cp
ON cr.CustomerID = cp.CustomerID
WHERE cp.[Product Category] in ('Nuts','Bolts','Screws','Spanners') )a
WHERE a.rnk = 1
答案 2 :(得分:1)
有一些技巧可以做这种查询(row_number或与分组数据连接),但我认为在你的情况下最干净的是使用外部应用:
select
cr.[CustomerID],
cr.[Company Name],
cr.[Company Segment],
cr.[Promo Code],
cn.[Note],
cp.[Product Category]
from tbl_Customer_Records as cr
left outer join tbl_Customer_Products as cp on cp.CustomerID = cr.CustomerID
outer apply (
select top 1
t.[Note]
from tbl_Customer_Notes as t
where t.[CustomerID] = cr.[CustomerID]
order by t.[Created_Date] desc
) as cn
where
cp.[Product Category] in ('Nuts','Bolts','Screws','Spanners')
将所有笨拙的table name.column name
更改为alias.column name
,我认为这种方式更具可读性。
或者:
select
cr.[CustomerID],
cr.[Company Name],
cr.[Company Segment],
cr.[Promo Code],
cn.[Note],
cp.[Product Category]
from tbl_Customer_Records as cr
left outer join tbl_Customer_Products as cp on cp.CustomerID = cr.CustomerID
left outer join tbl_Customer_Notes as cn on
cn.CustomerID = cr.CustomerID and
cn.[Created_Date] = (select max(t.[Created_Date]) from tbl_Customer_Notes as t where t.CustomerID = cr.CustomerID)
where
cp.[Product Category] in ('Nuts','Bolts','Screws','Spanners')
答案 3 :(得分:0)
尝试使用CustomerID not in (select CustomerID from tbl_Customer_Note)