SQL 新手。想将 IF(COUNTIFS()) Excel 公式转换为 SQL 代码并让 SQL 计算它而不是 Excel

Posted

技术标签:

【中文标题】SQL 新手。想将 IF(COUNTIFS()) Excel 公式转换为 SQL 代码并让 SQL 计算它而不是 Excel【英文标题】:New to SQL. Would like to convert an IF(COUNTIFS()) Excel formula to SQL code and have SQL calculate it instead of Excel 【发布时间】:2019-03-26 06:29:19 【问题描述】:

我正在运行 SQL Server 2008 R2 (RTM)。

我有一个提取日期、产品、客户和单位的 SQL 查询:

select 

[Transaction Date] as Date, 
[SKU] as Product, 
[Customer Name] as Customer, 
sum(Qty) as Units 

from dataset

where [Transaction Date] < '2019-03-01' and [Transaction Date] >= '2016-01-01'

group by [Transaction Date], [SKU], [Customer Name]

order by [Transaction Date]

这会提取数十万条记录,我想根据以下逻辑确定某个交易是新订单还是重新订单:

重新订购:该特定客户在过去 6 个月内订购了该特定产品

新订单:该特定客户在过去 6 个月内未订购该特定产品

为此,我在 Excel 中有这个公式似乎有效:

=IF(COUNTIFS(A$1:A1,">="&DATE(YEAR(A2),MONTH(A2)-6,DAY(A2)),C$1:C1,C2,B$1:B1,B2),"Reorder","New Order")

当我将其单独粘贴或粘贴到较小的数据集中时,该公式有效,但当我尝试将其复制粘贴到所有 500K+ 行时,Excel 放弃了,因为它为每个计算循环。

这可能在SQL中完成,但是我不知道如何将这个excel公式转换为SQL,我刚刚开始研究它。

【问题讨论】:

我们应该如何知道您的 Excel 单元格包含的内容,除了包含日期的 A2,请添加说明。还添加一些示例数据和预期输出。您使用的是什么数据库,请在您的问题中添加正确的标签。最后,那个 sql 查询真的有效吗,SUM() 函数通常需要 GROUP BY? 嗨乔金。对不起,这是我第一次在这里发帖。我不知道我的查询的 [where / group by/ order by] 部分与问题相关。除此之外,我不太了解您的其他准则。 A 列包含交易日期,A1 为标题。查询的预期输出是检查该客户是否在过去 6 个月内购买了该特定产品。如果是,则为重新订购,否则为新订单。 最好尽量减少,但不要太多,因为它可以使您不清楚您的代码是否有错误,关于 excel 代码,也许我读了很多,它与问题 服务器是Microsoft SQL Server 2008。 【参考方案1】:

您在查询开始时做得很好。您希望将三个附加函数添加到查询中。

您需要的第一件事是最简单的。 GETDATE() 只返回当前日期。当您将当前日期与交易日期进行比较时,您将需要它。

第二个函数是DATEDIFF,它将为您提供两个日期(月、日、年、季度等)之间的时间单位。使用DATEDIFF,您可以说“此日期是否在过去 6 个月内”。这个格式很简单。我是DATEDIFF(interval, date1, date2)

您要查找的第三个函数是CASE,它允许您告诉SQL 如果满足一个条件给您一个答案,但如果满足另一个条件则给您一个不同的答案。对于您的示例,您可以说“如果天数差异

把它们放在一起:

SELECT CASE 
        WHEN DATEDIFF(MONTH, [Transaction Date], GETDATE()) <= 6
            THEN 'Reorder'
        ELSE 'New Order'
        END as ORDER_TYPE
    ,[Transaction Date] AS DATE
    ,[SKU] AS PRODUCT
    ,[Customer Name] AS CUSTOMER
    ,Qty AS UNITS
FROM DATASET
有关 CASE 的其他示例,请查看此站点:https://www.w3schools.com/sql/sql_ref_case.asp 有关 DATEDIFF 的其他示例,请查看此处:请参阅 以下网页的示例和尝试的机会: https://www.w3schools.com/sql/func_sqlserver_datediff.asp

【讨论】:

您好 Moose,感谢您的详细回答!这没有所需的输出,它将直到某个日期的交易显示为所有新订单,然后每笔交易都是重新订购。我想要的是脚本检查该特定客户是否在过去 6 个月内购买了该特定产品,如果客户购买了,那么这将是重新订购,如果没有,那么它将是一个新订单。 【参考方案2】:
SELECT CASE
         WHEN Datediff(day, [transaction date], Getdate()) <= 180 THEN 'reorder'
         ELSE 'Neworder'
       END,
       [transaction date] AS Date,
       [sku]              AS Product,
       [customer name]    AS Customer,
       qty                AS Units
FROM   datase  

【讨论】:

除了代码,我认为你的回答应该解释它的作用。 特别是如果问题标题中的前三个单词是“SQL 新手”。 嗨洛基,谢谢您的回答!这没有所需的输出,它将直到某个日期的交易显示为所有新订单,然后每笔交易都是重新订购。我想要的是脚本检查该特定客户是否在过去 6 个月内购买了该特定产品,如果客户购买了,那么这将是重新订购,如果没有,那么它将是一个新订单。 【参考方案3】:

如果我理解正确,您想在前一天达到峰值并进行比较。这表明lag()

select (case when lag([Transaction Date]) over (partition by SKU, [Customer Name] order by [Transaction Date]) >
                  dateadd(month, -6, [Transaction Date])
             then 'Reorder'
             else 'New Order'
        end) as Order_Type
       [Transaction Date] as Date, 
       [SKU] as Product, 
       [Customer Name] as Customer, 
       sum(Qty) as Units 
from dataset d
group by [Transaction Date], [SKU], [Customer Name];

编辑:

在 SQL Server 2008 中,您可以使用 OUTER APPLY 模拟 LAG()

select (case when dprev.[Transaction Date] >
                  dateadd(month, -6, d.[Transaction Date])
             then 'Reorder'
             else 'New Order'
        end) as Order_Type
       d.[Transaction Date] as Date, 
       d.[SKU] as Product, 
       d.[Customer Name] as Customer, 
       sum(d.Qty) as Units 
from dataset d outer apply
     (select top (1) dprev.*
      from dataset dprev
      where dprev.SKU = d.SKU and
            dprev.[Customer Name] = d.[Customer Name] and
            dprev.[Transaction Date] < d.[Transaction Date]
      order by dprev.[Transaction Date] desc
     ) dprev
group by d.[Transaction Date], d.[SKU], d.[Customer Name];

【讨论】:

嗨,戈登。谢谢您的意见!正如我提到的,我还是 SQL 的新手,不知道我也必须将 SQL 服务器发布到我的问题中。我尝试运行滞后函数,它说“滞后”不是可识别的内置函数名称。之后我检查并发现延迟仅适用于 2012 年及以后,而我的服务器是 2008 年。

以上是关于SQL 新手。想将 IF(COUNTIFS()) Excel 公式转换为 SQL 代码并让 SQL 计算它而不是 Excel的主要内容,如果未能解决你的问题,请参考以下文章

Excel VBA Countifs 与循环

countifs为啥结果为0?

Excel中函数 if ifs count countif countifs 的区别是啥

EXCEL用countifs算出结果都为0?

SQL Countifs 和 Sumifs 函数

如何将此 COUNTIFS 转换为 Power Query 以获得更好的性能目的?