Sql 将产品与客户匹配的查询?
我们有各种各样的产品,每天都会添加很多 客户可以注册电子邮件提醒。这些邮件每天晚上都会批量发送,客户会收到一份定制的产品清单,这些产品符合他们的需求 数据库中有三个相关表: 帐户pk\U帐户ID、电子邮件地址、标题、名称 账户警报fk\U账户ID、主键警报ID、类别、最高价格、颜色 产品主打项ID、类别、标题、价格、颜色、日期修改 选择在过去24小时内添加的最新10种产品(与每位客户选择的选项相匹配)的最有效方法是什么 这是我到目前为止所做的工作,但它并没有只选择按日期排列的前10个产品,即最新添加的产品。我们不想通过电子邮件向客户发送30多种产品Sql 将产品与客户匹配的查询?,sql,sql-server,select,join,matching,Sql,Sql Server,Select,Join,Matching,我们有各种各样的产品,每天都会添加很多 客户可以注册电子邮件提醒。这些邮件每天晚上都会批量发送,客户会收到一份定制的产品清单,这些产品符合他们的需求 数据库中有三个相关表: 帐户pk\U帐户ID、电子邮件地址、标题、名称 账户警报fk\U账户ID、主键警报ID、类别、最高价格、颜色 产品主打项ID、类别、标题、价格、颜色、日期修改 选择在过去24小时内添加的最新10种产品(与每位客户选择的选项相匹配)的最有效方法是什么 这是我到目前为止所做的工作,但它并没有只选择按日期排列的前10个产品,即最新
SELECT
a.pk_AccountID,
aa.pk_AlertID,
a.Title As Title,
a.Name As Name,
a.EmailAddress As EmailAddress,
p.pk_ItemID As ItemID,
p.Category As Category,
p.Title As Title,
p.Price As Price,
p.Colour As Colour
FROM dbo.Accounts_Alerts aa
INNER JOIN dbo.Accounts a ON aa.fk_AccountID=a.pk_AccountID
LEFT OUTER JOIN dbo.Products p ON
(aa.Category = p.Category OR aa.Category IS NULL)
AND (aa.Colour = p.Colour OR aa.Colour IS NULL)
AND (aa.MaxPrice >= p.Price OR aa.MaxPrice IS NULL)
AND getdate()-1 < p.DateModified
WHERE
a.EmailAddress is not null AND
a.pk_AccountID = @AccountIDVariable
ORDER BY aa.pk_AlertID
处理此问题的常用方法是使用窗口函数和内联视图,SQL Server对此处理得相当好 例如:
SELECT
pk_AccountID,
pk_AlertID,
Title,
Name,
EmailAddress,
ItemID,
Category,
Title,
Price,
Colour
FROM (
SELECT
a.pk_AccountID,
aa.pk_AlertID,
a.Title As Title,
a.Name As Name,
a.EmailAddress As EmailAddress,
p.pk_ItemID As ItemID,
p.Category As Category,
p.Title As Title,
p.Price As Price,
p.Colour As Colour,
ROW_NUMBER() over (
partition by a.pk_AccountID, p.pk_ItemID
order by p.DateModified desc
) as rseq
FROM dbo.Accounts_Alerts aa
INNER JOIN dbo.Accounts a ON aa.fk_AccountID=a.pk_AccountID
LEFT OUTER JOIN dbo.Products p ON
(aa.Category = p.Category OR aa.Category IS NULL)
AND (aa.Colour = p.Colour OR aa.Colour IS NULL)
AND (aa.MaxPrice >= p.Price OR aa.MaxPrice IS NULL)
AND getdate()-1 < p.DateModified
WHERE
a.EmailAddress is not null AND
a.pk_AccountID = @AccountIDVariable
) as any_alias_will_do
where rseq <= 10
ORDER BY pk_AlertID
请注意ROW_NUMBER函数-您需要确保按照我在此处选择的帐户ID和项目ID的正确标准进行分区和排序,但您可能需要不同的字段。尝试单独运行内部查询,以帮助您了解其工作原理
此技术用途广泛-建议您进一步阅读这些函数。您可以使用前10名获得10行。如果您需要每个用户的前10名产品,您可以在查询中添加行数或排名,按用户进行分区,并将其限制为窗口功能非常适合此功能。使用partitionby,每个客户返回10行。如果您添加了一个查询,我相信会有人帮助您重写查询。非常感谢您的帮助。不幸的是,在编辑您的代码以添加我需要的更多字段并对其进行测试后,它始终需要很长时间1分钟以上,有时还会出现内存不足错误。将过去24小时内的产品选择到一个临时表中,并为每个警报从中进行选择是否会更快?我用一个临时表进行了尝试,结果使情况变得更糟。4分钟过去了,然后没有记忆了。然后我将其回滚到直接使用产品表,现在每次都会出现内存不足的情况。@TVRV8S首先,我相信你所说的,如果没有更多的洞察力,我无法解决它,但我有一些建议给你。第二,这种查询风格是普遍存在的,并且得到了很好的支持,所以它不应该太慢!!!第三,要优化导致问题的内容,您需要熟悉表上定义的索引,以及查询的执行计划-执行计划应该告诉您什么使用了最多的资源,并引导您找到解决方案。当然,你可以完全忽略这项技术,但我自己已经用得够多了,我想把它留给你: