Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
面向核心SQL设计器的复杂选择查询问题_Sql_Sql Server_Sql Server 2005 - Fatal编程技术网

面向核心SQL设计器的复杂选择查询问题

面向核心SQL设计器的复杂选择查询问题,sql,sql-server,sql-server-2005,Sql,Sql Server,Sql Server 2005,几天来,非常复杂的查询一直在尝试构建它,并取得了更大的成功 我使用的是SQL-SERVER 2005标准 我需要的是: 来自活动的5个活动变体,其中2个具有最大的PPU编号集,3个为随机变量 下一个条件是,CampaignDailyBudget和CampaignTotalBudget低于Campaign calculation中设置的值,即Visitors表中通过用户单击的活动变体连接到活动的点击次数 下一个条件活动语言、活动类别、活动地区和活动国家必须是我发送给此选择的带有languageID

几天来,非常复杂的查询一直在尝试构建它,并取得了更大的成功

我使用的是SQL-SERVER 2005标准

我需要的是:
来自活动的5个活动变体,其中2个具有最大的PPU编号集,3个为随机变量

下一个条件是,CampaignDailyBudget和CampaignTotalBudget低于Campaign calculation中设置的值,即Visitors表中通过用户单击的活动变体连接到活动的点击次数

下一个条件活动语言、活动类别、活动地区和活动国家必须是我发送给此选择的带有languageID、categoryID、regionID和countryID的选项

下一个条件是,我发送到此select语句的IP地址将不在当前活动的IP列表中,我将删除24小时不活动的IP

换句话说,当我从用户PublisherRegionUID、IP、Language、Country和Region获取数据时,它会为进入站点的用户获取5个活动变量

更多细节

我从访问者那里获得countryID、regionID、ipID、PublisherRegionID和languageID。这是过滤器参数。虽然我首先需要了解出版商将要在其网站上展示的内容,包括类别、语言等等。。。。然后,我用除PublisherRegionUID之外的所有参数按访问者的参数过滤所有剩余的活动

所以它有两个真正的过滤器。一个是发布者想要发布的内容,另一个是访问者可以查看的内容

campaignDailyBudget和campaignTotalBudget是由创建活动的用户设置的值。这两个数字与每个活动的点击次数相比*活动PPU,而日期过滤器显然用于过滤今天上午12:00到晚上11:59的活动每日预算。由于明显的原因,campaignTotalBudget未按日期筛选

存储过程演示


我不确定我是否理解你文章的这一部分:

它为用户获取5个活动变量 当我从 使用者 PublisherRegionUID、IP、语言、国家 及地区

我想这就是问题所在。给你第二个条件的用户是IP?当我从用户那里获取信息意味着什么?这是否意味着这是您在执行查询时拥有的信息,还是您从查询中返回的信息?如果是后者,那么就有许多问题需要回答,因为这些专栏中的许多都是多:多关系的一部分

不管怎样,下面是获得5个活动的方法,根据您的第二个下一个条件,您有一个要过滤掉的IP地址。我还假设你总共想要五个活动,这意味着三个随机活动不能包括两个最高的PPU活动

With 
    ValidCampaigns As
    (
    Select C.campaignId
    From Campaigns As C
        Left Join (Campaigns2IPs As CIP
            Join IPs
                On IPs.ipID = CIP.ipID
                    And IPs.ipAddress = @IPAddress)
            On CIP.campaignId = C.campaignId
    Where CIP.campaignID Is Null
    )
    CampaignPPURanks As
    (
    Select C.campaignId
        , Row_Number() Over ( Order By C.campaignPPU desc ) As ItemRank
    From ValidCampaigns As C
    )
    , RandomRanks As
    (
    Select campaignId
        , Row_Number() Over ( Order By newid() desc ) As ItemRank
    From ValidCampaigns As C
        Left Join CampaignPPURanks As CR
            On CR.campaignId = C.campaignId
                And CR.ItemRank <= 2
    Where CR.campaignId Is Null
    )
Select ...
From CampaignPPURanks As CPR
    Join CampaignVariants As CV
        On CV.campaignId = CPR.campaignId
            And CPR.ItemRank <= 2 
Union All           
Select ...
From RandomRanks As RR
    Join CampaignVariants As CV
        On CV.campaignId = RR.campaignId
            And RR.ItemRank <= 3 

我不确定我是否理解你文章的这一部分:

它为用户获取5个活动变量 当我从 使用者 PublisherRegionUID、IP、语言、国家 及地区

我想这就是问题所在。给你第二个条件的用户是IP?当我从用户那里获取信息意味着什么?这是否意味着这是您在执行查询时拥有的信息,还是您从查询中返回的信息?如果是后者,那么就有许多问题需要回答,因为这些专栏中的许多都是多:多关系的一部分

不管怎样,下面是获得5个活动的方法,根据您的第二个下一个条件,您有一个要过滤掉的IP地址。我还假设你总共想要五个活动,这意味着三个随机活动不能包括两个最高的PPU活动

With 
    ValidCampaigns As
    (
    Select C.campaignId
    From Campaigns As C
        Left Join (Campaigns2IPs As CIP
            Join IPs
                On IPs.ipID = CIP.ipID
                    And IPs.ipAddress = @IPAddress)
            On CIP.campaignId = C.campaignId
    Where CIP.campaignID Is Null
    )
    CampaignPPURanks As
    (
    Select C.campaignId
        , Row_Number() Over ( Order By C.campaignPPU desc ) As ItemRank
    From ValidCampaigns As C
    )
    , RandomRanks As
    (
    Select campaignId
        , Row_Number() Over ( Order By newid() desc ) As ItemRank
    From ValidCampaigns As C
        Left Join CampaignPPURanks As CR
            On CR.campaignId = C.campaignId
                And CR.ItemRank <= 2
    Where CR.campaignId Is Null
    )
Select ...
From CampaignPPURanks As CPR
    Join CampaignVariants As CV
        On CV.campaignId = CPR.campaignId
            And CPR.ItemRank <= 2 
Union All           
Select ...
From RandomRanks As RR
    Join CampaignVariants As CV
        On CV.campaignId = RR.campaignId
            And RR.ItemRank <= 3 

我还对您的需求做了一些假设。我会一边解释代码一边把它们拼出来。请注意,我当然没有合理的方法来测试这段代码的打字错误或轻微的逻辑错误

也许可以将其作为一个巨大的查询来编写,但这样做会很尴尬、难看,并且容易出现性能问题,因为SQL优化器在为过大的查询构建计划时可能会遇到问题。一个选项是将其编写为一系列查询,填充临时表以便在后续查询中使用,这样可以简化调试。我选择将其编写为一个包含一系列CTE表的大型通用表表达式语句,主要是因为它以这种方式“流动”得更好,并且可能比许多temp表版本的性能更好

第一个假设:这里有几个循环引用。Campaign同时具有到国家和地区的链接,因此必须检查这两个参数值,即使基于从国家到地区的表链接,此筛选器可能会简化为仅检查国家,假设国家参数值始终“在”地区参数中。这同样适用于语言和类别,也可能适用于IP和访问者。这似乎是草率的设计 gn;如果可以澄清,或者可以对数据的有效性做出假设,查询就可以简化

第二种假设:参数以@Region、@Country等形式作为变量传入,并且只传入一个IP地址;如果没有,那么您需要传入多个值,设置一个包含这些值的临时表,并将其添加为我使用@IP参数的过滤器

因此,第1步是第一步,通过提取所有共享所需国家、地区、语言、类别,并且没有与之关联的IP地址的活动,确定“合格”活动:

WITH cteEligibleCampaigns (CampaignId)
 as (select CampaignId
      from Campaigns2Regions
      where RegionId = @RegionId
     intersect select CampaignId
      from Campaign2Countries
      where CountryId = @CountryId
     intersect select CampaignId
      from Campaign2Languages
      where LanguageId = @LanguageId
     intersect select CampaignId
      from Campaign2Categories
      where CategoryId = @CategoryId
     except select CampaignId
      from Campaigns2IPs
      where IPID = @IPId)
接下来,从这些列表中筛选出“活动每日预算和活动总预算低于活动计算中设置的是访问者表中通过用户单击的活动变体连接到活动的点击次数”的项目。这个要求我并不完全清楚。我选择将其解释为“仅包括那些活动,如果您计算这些活动的活动变体的访问者数量,则总数小于活动DailyBudget和活动TotalBudget”。请注意,这里我引入了一个随机值,稍后用于选择随机行

,cteTargetCampaigns (CampaignId, RandomNumber)
  as (select CampaignId, checksum(newid() RandomNumber)
       from cteEligibleCampaigns ec
        inner join Campaigns ca
         on ca.CampgainId = ec.CampaignId
        inner join CampaignVariants cv
         on cv.CampgainId = ec.CampaignId
        inner join CampaignVariants2Visitors cvv
         on cvv.CampaignVariantId = cv. CampaignVariantId
       group by ec.CampaignId
       having count(*) < ca.CampaignDailyBudget
        and count(*) < CampaignTotalBudget)
接下来,按随机分配的编号排列所有其他活动:

,cteRandom (CampaignId, Ranking)
  as (select CampaignId, row_number() over (order by RandomNumber)
       from cteTargetCampaigns
       where CampaignId not in (select CampaignId
                                 from cteTopTwo
                                 where Ranking < 3))
最后,将数据集拉到一起:

 select CampaignId
  from cteTopTwo
  where Ranking <= 2
 union all select CampaignId
  from cteRandom
  where Ranking <= 3

将以上代码部分放在一起,调试错误,无效假设,以及遗漏的需求,例如从随机项中识别前两项的顺序或标志,你应该是好的。

我还对你的需求做了一些假设。我会一边解释代码一边把它们拼出来。请注意,我当然没有合理的方法来测试这段代码的打字错误或轻微的逻辑错误

也许可以将其作为一个巨大的查询来编写,但这样做会很尴尬、难看,并且容易出现性能问题,因为SQL优化器在为过大的查询构建计划时可能会遇到问题。一个选项是将其编写为一系列查询,填充临时表以便在后续查询中使用,这样可以简化调试。我选择将其编写为一个包含一系列CTE表的大型通用表表达式语句,主要是因为它以这种方式“流动”得更好,并且可能比许多temp表版本的性能更好

第一个假设:这里有几个循环引用。Campaign同时具有到国家和地区的链接,因此必须检查这两个参数值,即使基于从国家到地区的表链接,此筛选器可能会简化为仅检查国家,假设国家参数值始终“在”地区参数中。这同样适用于语言和类别,也可能适用于IP和访问者。这似乎是草率的设计;如果可以澄清,或者可以对数据的有效性做出假设,查询就可以简化

第二种假设:参数以@Region、@Country等形式作为变量传入,并且只传入一个IP地址;如果没有,那么您需要传入多个值,设置一个包含这些值的临时表,并将其添加为我使用@IP参数的过滤器

因此,第1步是第一步,通过提取所有共享所需国家、地区、语言、类别,并且没有与之关联的IP地址的活动,确定“合格”活动:

WITH cteEligibleCampaigns (CampaignId)
 as (select CampaignId
      from Campaigns2Regions
      where RegionId = @RegionId
     intersect select CampaignId
      from Campaign2Countries
      where CountryId = @CountryId
     intersect select CampaignId
      from Campaign2Languages
      where LanguageId = @LanguageId
     intersect select CampaignId
      from Campaign2Categories
      where CategoryId = @CategoryId
     except select CampaignId
      from Campaigns2IPs
      where IPID = @IPId)
接下来,从这些列表中筛选出“活动每日预算和活动总预算低于活动计算中设置的是访问者表中通过用户单击的活动变体连接到活动的点击次数”的项目。这个要求我并不完全清楚。我选择将其解释为“仅包括那些活动,如果您计算这些活动的活动变体的访问者数量,则总数小于活动DailyBudget和活动TotalBudget”。请注意,这里我引入了一个随机值,稍后用于选择随机行

,cteTargetCampaigns (CampaignId, RandomNumber)
  as (select CampaignId, checksum(newid() RandomNumber)
       from cteEligibleCampaigns ec
        inner join Campaigns ca
         on ca.CampgainId = ec.CampaignId
        inner join CampaignVariants cv
         on cv.CampgainId = ec.CampaignId
        inner join CampaignVariants2Visitors cvv
         on cvv.CampaignVariantId = cv. CampaignVariantId
       group by ec.CampaignId
       having count(*) < ca.CampaignDailyBudget
        and count(*) < CampaignTotalBudget)
接下来,按随机分配的编号排列所有其他活动:

,cteRandom (CampaignId, Ranking)
  as (select CampaignId, row_number() over (order by RandomNumber)
       from cteTargetCampaigns
       where CampaignId not in (select CampaignId
                                 from cteTopTwo
                                 where Ranking < 3))
最后,将数据集拉到一起:

 select CampaignId
  from cteTopTwo
  where Ranking <= 2
 union all select CampaignId
  from cteRandom
  where Ranking <= 3

把上面的代码部分放在一起,调试错误,无效假设,以及遗漏的需求,比如从随机项中识别前两项的顺序或标志,你应该做得很好。

你的问题还不够清楚。请至少提供您的表说明。表定义、示例数据和预期输出将非常有用。当一个人试图描述它时,通常很难理解他在寻找什么,特别是当他使用的术语别人可能不熟悉时。@redben和@Tom H,在5次活动后的底部有一个图表图像,其中2次是PPU较高的,3次是ra

ndom还不清楚。当你说“然而”时,你的意思是在哪里?你说的更高是什么意思?你说的最高是什么意思。请至少提供您的表说明。表定义、示例数据和预期输出将非常有用。当一个人试图描述它时,通常很难理解他在寻找什么,特别是当他使用的术语别人可能不熟悉时。@redben和@Tom H.,在post5活动的底部有一个图表图像,其中有两个活动的变体具有较高的PPU,3个是随机的,不清楚。当你说“然而”时,你的意思是在哪里?你说的更高是什么意思,你说的最高是什么意思,即最大,最大?添加了更多信息以排除我最初问题中的错误鉴于OP的修订,这几乎是我应该采取的方法+1在构建活动列表时使用intersect和except。和@Thomas,非常感谢您的回复,我会在这里和那里进行一些修改以适应,但此查询的框架非常重要,而你们两人给了我更多。添加了更多信息以排除我最初问题中的错误鉴于OP的修订,这几乎是我应该采取的方法+1用于创建活动列表时使用intersect和except。和@Thomas,非常感谢您的回复。我会在这里和那里进行一些修改,以适合您的需要,但这个查询的框架非常重要,而你们两人都给了我更多。@eugeneK,告诉我们这有什么问题可能会有所帮助。@Lieven,已排除PublisherRegionId筛选器。Publisher可以设置其网站中显示的项目的类别、语言、国家和地区。因此,我必须考虑到这一点。@eugeneK,告诉我们这有什么问题可能会有帮助。@Lieven,PublisherRegionUID过滤器被排除在外。Publisher可以设置其网站中显示的项目的类别、语言、国家和地区。因此,我必须考虑到这一点。