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的主要内容,如果未能解决你的问题,请参考以下文章