我对sql查询比较新,我想知道如何创建一个复杂的存储过程。我的数据库在SQL服务器上运行。
我有一个表customer(id,name)和一个表customer_events(id,customer_id,timestamp,action_type)。我想将一个计算字段customer_status添加到表客户
我可以使用if-then-else结构,还是应该以不同的方式解决这个挑战?
答案 0 :(得分:0)
假设您将事件信息输入“Most_Recent_Event_Mins_Ago”。如果没有,它将是NULL。
SELECT Id, Name,
CASE
WHEN Most_Recent_Event_Mins_Ago IS NULL THEN 0
WHEN Most_Recent_Event_Mins_Ago <5 AND Action_type = 0 THEN 1
WHEN Most_Recent_Event_Mins_Ago <5 AND Action_type = 1 THEN 0
..other scenarions
ELSE yourDefaultValueForStatus
END as Status
FROM customer
WHERE
...
...
答案 1 :(得分:0)
正如您在评论中提到的,您实际上想要向选择查询添加字段,并且在一般意义上,您想要的是CASE
语句。他们的工作方式如下:
SELECT field1,
field2,
CASE
WHEN some_condition THEN some_result
WHEN another_condition THEN another_result
END AS field_alias
FROM table
应用于您的特定场景,这并非完全直截了当。您肯定需要left join
您的状态表,您还希望聚合以查找最新事件以及该事件的操作类型。一旦掌握了这些信息,案例陈述就很简单。
在没有数据访问权限的情况下编写sql总是很难,但是类似于:
SELECT c.id,
c.name,
CASE
WHEN e.id IS NULL OR DATEDIFF(minute,e.timestamp,getDate())>=5 THEN 0
WHEN DATEDIFF(minute,e.timestamp,getDate())<5 AND s.action_type=1 THEN 1
WHEN DATEDIFF(minute,e.timestamp,getDate())<5 AND s.action_type=0 THEN 2
END as customer_status
FROM clients c
LEFT JOIN (
SELECT id, client_id, action_type,
rank() OVER(partition by client_id order by timestamp desc) AS r
FROM customer_events
) e
ON c.id=e.client_id AND e.r=1
这个核心是中间的子查询,它使用rank
功能通过按时间戳降序排序的client_id
为每个状态提供一个数字。因此,排名为1
的每个记录都将是最新的(对于该客户端)。此后,您只需将其加入到客户端表中,并使用它来确定customer_status
的正确值