我创建了一个很好的查询来观看进入我网站的所有唯一IP。架构如下:
Page_Statistic - 包含每个页面点击的数据(每次点击一个记录)。
Ip_Location_Info - 包含每个访问者的位置数据(每个ip一个记录)。
我想获得所有唯一的IP地址,包括地点,访问次数,时间范围,以及他们是否在我的网站上尝试过该演示 - 而最后一部分就是我遇到的问题。如果他们尝试过该演示,我想要1,如果他们没有尝试,我想要0。如果在Page_Statistic中存在一个tupple并且标签设置为' demo',则IP已经尝试了该演示。
我已经创建了以下查询来解决此问题:
WITH uniqueips(frst, lst, ip, visits) AS
(
SELECT MIN(requested_on), MAX(requested_on), ip, count(*) AS visits
FROM Page_Statistic p
GROUP BY ip
),
tried_demo(ip, tried_demo) AS
(
SELECT DISTINCT ip.ip, ISNULL(p.page_statistic_id - p.page_statistic_id + 1, 0)
FROM uniqueips ip
LEFT JOIN Page_Statistic p ON p.ip = ip.ip AND p.tag = 'demo'
)
SELECT
i.*, ip.frst AS first_appeared_on,
ip.lst AS last_appeared_on,
ip.visits,
d.tried_demo
FROM Ip_Location_Info i
JOIN uniqueips ip ON ip.ip = i.ip
JOIN tried_demo d ON ip.ip = d.ip
ORDER BY ip.frst
但丑陋的部分是我为Try_demo设置1或0的地方。
ISNULL(p.page_statistic_id - p.page_statistic_id + 1, 0)
这是有效的,因为如果p.page_statistic_id为null,则将null添加为null为空,因此isnull将返回params(0)列表中的第二项。这是一个黑客!这样做的正确方法是什么?
答案 0 :(得分:2)
你有它的方式,所以这很好,但如果你想改变它,你可以改为
case when p.page_statistic_id is null then 0 else 1 end
OR
将您的ted_demoCTE更改为此
tried_demo(ip, tried_demo) AS
(
SELECT DISTINCT p.ip, cast(1 as bit)
FROM Page_Statistic
WHERE p.tag = 'demo'
)
然后您的选择可以像这样
SELECT
i.*, ip.frst AS first_appeared_on,
ip.lst AS last_appeared_on,
ip.visits,
coalesce(d.tried_demo,0) as tried_demo
FROM Ip_Location_Info i
JOIN uniqueips ip ON ip.ip = i.ip
LEFT JOIN tried_demo d ON ip.ip = d.ip
ORDER BY ip.frst