简体   繁体   中英

SQL query returning a column of 1 if a condition is met and 0 otherwise

I've created a nice query to watch all the unique IPs entering my site. The schema is as follows:

Page_Statistic - Contains data on each page hit (one record per hit).

  • page_statistic_id.
  • ip - ip address of visitor.
  • tag - used to record special things, like "demo" if they tried the demo.
  • url - of the page they visited.
  • requested_on - time of visit.

Ip_Location_Info - Contains location data on each visitor (one record per ip).

  • ip
  • country
  • region
  • city
  • zip

I want to get all the unique IP addresses, with locations, number of visits, time range, and whether they tried the demo on my website - and this last part is what I'm having trouble with. I want a 1 if they've tried the demo, and 0 if they haven't. An IP has tried the demo iff a tupple exists in Page_Statistic with tag set to 'demo'.

I've created the following query which solves this:

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

But the ugly part is where I set the 1 or 0 for tried_demo.

ISNULL(p.page_statistic_id - p.page_statistic_id + 1, 0)

This works because if p.page_statistic_id is null, adding 1 to null is null so isnull will return the second item in the list of params (0). It's such a hack! What is the correct way to do this?

The way you have it works, so that's good, but if you wanted to change it, you could change it to

case when p.page_statistic_id is null then 0 else 1 end

OR

change your tried_demo CTE to this

tried_demo(ip, tried_demo) AS
(
    SELECT DISTINCT p.ip, cast(1 as bit) 
    FROM Page_Statistic 
    WHERE p.tag = 'demo'
)

then your select can be like this

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM