我正在尝试找到重复的“密钥”,这样它们就可以被寻址并制作成正确的唯一密钥。
我最近了解到HAVING子句可以通过定位GROUP BY的结果来过滤聚合查询的结果。你按照所谓的“密钥”进行分组并且计算的地点是> 1,还有你的问题行。
我的问题是,窗口函数的等价物是什么?
下表对于名称和月份只应该是原子的,但是它使用的是日期详细的日期字段(例如,某些事情可能会在一个月内出现两次或更多次,而应该只是每月一次)。 / p>
select
event_id,
overly_specific_date,
count(*) over(partition by event_id, substring(convert(char(8), overly_specific_date), 0, 7))
from events_historic
order by over(partition by event_id, substring(convert(char(8), overly_specific_date), 0, 7))
VS
select
event_id,
count(*)
from events_historic
group by event_id, substring(convert(char(8), overly_specific_date), 0, 7)
having count(*) > 1
第一个查询很好,因为它显示了我想要的内容,但我想将其过滤掉。我知道我可以在更大的查询或CTE中做到这一点,但我正在寻找像HAVING这样简洁的东西。第二个查询使用HAVING,但它不再显示键的一部分,overly_specific_date。
如何过滤第二个查询?
答案 0 :(得分:0)
CTE版本:
WITH events AS (
SELECT t.event_id,
COUNT(*) 'num'
FROM EVENTS_HISTORIC t
GROUP BY e.event_id, YEAR(t.date), MONTH(t.date), DAY(t.date)
HAVING COUNT(*) > 1)
SELECT eh.event_id,
eh.date,
e.num
FROM EVENTS_HISTORIC eh
JOIN events e ON e.event_id = eh.event_id
非CTE版本:
SELECT eh.event_id,
eh.date,
e.num
FROM EVENTS_HISTORIC eh
JOIN (SELECT t.event_id,
COUNT(*) 'num'
FROM EVENTS_HISTORIC t
GROUP BY e.event_id, YEAR(t.date), MONTH(t.date), DAY(t.date)
HAVING COUNT(*) > 1) e ON e.event_id = eh.event_id
答案 1 :(得分:0)
你的问题是overly_specific_date在一个组中有所不同(你按日期版本的日期聚合),因此无法显示overly_specific_date,因为该组不存在单个值。要列出所有违规日期,您必须实现rexem提出的某种子查询,以将该组链接到不同的日期。
然而,一个可能符合您目的的廉价黑客是在原始查询中选择overly_specific_date的MIN / MAX,以显示正在出现的违规日期范围。 (如果你想要的话,你也可以将月份版本转储到MIN语句中。)
答案 2 :(得分:0)
我推荐一个CTE,但是既然你问过,使用TOP(1)WITH TIES有一种偷偷摸摸的方法:
select top (1) with ties
event_id,
overly_specific_date,
count(*) over (
partition by event_id,
substring(convert(char(8), overly_specific_date), 0, 7)
) as ct
from events_historic
order by
case when count(*) over (
partition by event_id,
substring(convert(char(8), overly_specific_date), 0, 7)
) > 1 then 0 else 1 end;
这并没有概括到许多其他有用的情况,但我认为在你的情况下它会起作用。