SQL:遍历子查询

时间:2019-02-21 15:13:33

标签: sql sql-server tsql

我当前正在处理一个查询,该查询标记最近10天内所有电子邮件地址与其他任何订单都不相同的订单。

现在,我可以检查最近的订单是否少于10天,但是否有3个订单:

1. 2019/01/01
2. 2019/01/20
3. 2019/01/22

然后所有这些都将得到是,因为nr 3将检查nr 1。 因此,我需要在子查询中建立一个循环,以遍历所有具有相同电子邮件地址的子查询。请帮忙:)

SELECT TOP (1000)       
        OnlyOneWithin10Days =  
                CASE   
                WHEN (select top (1) inner.CreationDate 
                    from [Database].[req].[PersonalDetail] as pd1 
                    JOIN req.OfferRequest ofreq on ofreq.MainDriverPersonalDetailID = inner.ID
                    JOIN rsp.InsuranceResponse inresp on ofreq.InsuranceResponseID = inresp.id
                    JOIN adm.ProductBundle inner2 on inresp.ProductBundleID = inner2.ID
                    where inner.Email = personalDetail.Email 
                    and inner2.ID = pb.ID
                    and personalDetail.id > inner.ID
                    and inner.CreationDate < personalDetail.CreationDate
                    order by inner.CreationDate desc) is NULL

                OR  datediff(MINUTE, (select top (1) inner.CreationDate 
                    from [Database].[req].[PersonalDetail] as inner 
                    JOIN req.OfferRequest ofreq on ofreq.MainDriverPersonalDetailID = inner.ID
                    JOIN rsp.InsuranceResponse inresp on ofreq.InsuranceResponseID = inresp.id
                    JOIN adm.ProductBundle inner2 on inresp.ProductBundleID = inner2.ID
                    where inner.Email = personalDetail.Email 
                    and inner2.ID = pb.ID
                    and personalDetail.id > inner.ID
                    and inner.CreationDate < personalDetail.CreationDate
                    --and datediff(MINUTE, inner.CreationDate, personalDetail.CreationDate) >= 10
                    order by inner.CreationDate desc), personalDetail.CreationDate) >= 10

                THEN 'Yes'
                ELSE 'No'
                END 
        ,personalDetail.CreationDate
        ,pb.Name product
        ,personalDetail.Name
        ,personalDetail.email
        ,i.Name insurance

  FROM [Database].[req].[OfferRequest] as oreq

  JOIN req.PersonalDetail personalDetail on oreq.MainDriverPersonalDetailID = personalDetail.ID
  JOIN rsp.InsuranceResponse ir on oreq.InsuranceResponseID = ir.ID
  JOIN adm.ProductBundle pb on ir.ProductBundleID = pb.ID
  JOIN adm.Insurance i on pb.InsuranceID = i.ID


  order by personalDetail.Email, personalDetail.CreationDate

编辑:我正在使用SSMS(Microsoft SQL Server Management Studio 14.0.17289.0)

Edit2:很抱歉,如果我的问题有点令人困惑,但是我是stackOverflow的新手。

结果应该像这样

enter image description here

1 个答案:

答案 0 :(得分:0)

您发布了您想要的东西,所以这里是如何做的-请在了解具体需要什么之前,从下面获取有关此工作方式的详细信息:

SELECT TABLE1.*, CASE WHEN SUB.PRIOR = 0 THEN 'YES' ELSE 'NO' END AS OnlyEmail10days 
FROM TABLE1 
JOIN (
  SELECT BASE.EMAIL, COUNT(PROIR.EMAIL) AS PRIOR
  FROM TABLE1 AS BASE
  LEFT JOIN TABLE1 AS PRIOR ON BASE.EMAIL = PROIR.EMAIL AND DATEDIFF(day, PRIOR.DATE, BASE.DATE) <= 10
  GROUP BY BASE.EMAIL
) AS SUB ON SUB.EMAIL = TABLE1.EMAIL

当然TABLE1。*是这里的占位符,但是在您想要TABLE1的确切字段中。


我不理解您的代码,但这是您问题的答案:

假设您有一个名为TABLE1的表,它具有一个名为EMAIL的字段和一个名为DATE的字段

以下查询

 SELECT BASE.EMAIL, COUNT(PRIOR.EMAIL) AS CNT
 FROM TABLE1 AS BASE
 JOIN TABLE1 AS PRIOR ON BASE.EMAIL = PROIR.EMAIL AND DATEDIFF(day, PRIOR.DATE, BASE.DATE) <= 10
 GROUP BY BASE.EMAIL

将返回最近10天内使用同一封电子邮件的所有行以及计数。

希望这会有所帮助。这就是SQL的工作方式,它使用集合而不是迭代。

它的工作方式是使用联接-联接是一个集合函数-我们为电子邮件和10天相同的项目集定义条件,SQL一次查找所有这些。我们只希望对它们进行计数,这就是我们返回的结果(如果不需要计数,只需将该字段留在结果集中即可。)

如果您只希望最近10天内没有电子邮件地址的项目,请使用以下查询:

 SELECT BASE.EMAIL
 FROM TABLE1 AS BASE
 LEFT JOIN TABLE1 AS PRIOR ON BASE.EMAIL = PROIR.EMAIL AND DATEDIFF(day, PRIOR.DATE, BASE.DATE) <= 10
 WHERE PRIOR.EMAIL IS NULL

这里我们做的和以前一样,但是因为它是左联接,所以我们可以采用没有任何联接元素的集合。