Sql 将产品与客户匹配的查询?

Sql 将产品与客户匹配的查询?,sql,sql-server,select,join,matching,Sql,Sql Server,Select,Join,Matching,我们有各种各样的产品,每天都会添加很多 客户可以注册电子邮件提醒。这些邮件每天晚上都会批量发送,客户会收到一份定制的产品清单,这些产品符合他们的需求 数据库中有三个相关表: 帐户pk\U帐户ID、电子邮件地址、标题、名称 账户警报fk\U账户ID、主键警报ID、类别、最高价格、颜色 产品主打项ID、类别、标题、价格、颜色、日期修改 选择在过去24小时内添加的最新10种产品(与每位客户选择的选项相匹配)的最有效方法是什么 这是我到目前为止所做的工作,但它并没有只选择按日期排列的前10个产品,即最新

我们有各种各样的产品,每天都会添加很多

客户可以注册电子邮件提醒。这些邮件每天晚上都会批量发送,客户会收到一份定制的产品清单,这些产品符合他们的需求

数据库中有三个相关表:

帐户pk\U帐户ID、电子邮件地址、标题、名称 账户警报fk\U账户ID、主键警报ID、类别、最高价格、颜色 产品主打项ID、类别、标题、价格、颜色、日期修改 选择在过去24小时内添加的最新10种产品(与每位客户选择的选项相匹配)的最有效方法是什么

这是我到目前为止所做的工作,但它并没有只选择按日期排列的前10个产品,即最新添加的产品。我们不想通过电子邮件向客户发送30多种产品

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首先,我相信你所说的,如果没有更多的洞察力,我无法解决它,但我有一些建议给你。第二,这种查询风格是普遍存在的,并且得到了很好的支持,所以它不应该太慢!!!第三,要优化导致问题的内容,您需要熟悉表上定义的索引,以及查询的执行计划-执行计划应该告诉您什么使用了最多的资源,并引导您找到解决方案。当然,你可以完全忽略这项技术,但我自己已经用得够多了,我想把它留给你: