Извлечение и сравнение цифр в определенной позиции в BigQuery - PullRequest
0 голосов
/ 27 сентября 2018

Как можно сравнить несколько фрагментов данных, чтобы можно было найти различия строк в последних двух символах перед символом данных?

Так что, если у меня, например, были электронные письма, и я хотел получать только случаигде разница между двумя электронными письмами в последних двух символах до «@» составляла 1 символ, только если между ними был создан день.Итак -

т.е.

samfake@gmail.com              2018-09-01
johnslife@googlio.com          2018-09-20
samfake1@gmail.com             2018-09-02
sarahshouse@yahoo.com          2018-08-01
sarahshouse4@yahoo.com         2018-08-01
samfake4@gmail.com             2018-08-02
notgoing@hotmail.com           2016-02-04
notgoing3@hotmail.com          2018-05-04

, и я хотел увидеть что-то, где я мог бы получить эти письма:

samfake@gmail.com
samfake1@gmail.com
sarahshouse@yahoo.com
sarahshouse4@yahoo.com
samfake4@gmail.com

Где последние цифры перед знаком '@'отличаются на 1, по сравнению, по крайней мере, с 1 другим электронным письмом, учитывая, что сравниваемые данные находятся в пределах друг от друга дня.Было бы здорово указать условие, при котором оставшаяся часть письма должна оставаться неизменной во время этих сравнений в SQL.Таким образом, единственное место, где символьная разница = 1, - это последние цифры перед '@'

Ответы [ 2 ]

0 голосов
/ 27 сентября 2018

Ниже для BigQuery Standard SQL

#standardSQL
WITH `project.dataset.table` AS (
  SELECT 'samfake@gmail.com' email, DATE '2018-09-01' dt UNION ALL
  SELECT 'johnslife@googlio.com', '2018-09-20' UNION ALL
  SELECT 'samfake1@gmail.com', '2018-09-02' UNION ALL
  SELECT 'sarahshouse@yahoo.com', '2018-08-01' UNION ALL
  SELECT 'sarahshouse4@yahoo.com', '2018-08-01' UNION ALL
  SELECT 'samfake4@gmail.com', '2018-08-02' UNION ALL
  SELECT 'notgoing@hotmail.com', '2016-02-04' UNION ALL
  SELECT 'notgoing3@hotmail.com', '2018-05-04' 
), temp AS (
  SELECT domain,
    ARRAY_AGG(user) OVER(PARTITION BY domain ORDER BY day 
    RANGE BETWEEN 1 PRECEDING AND CURRENT ROW) users
  FROM (
    SELECT UNIX_DATE(dt) day, 
      SUBSTR(email, STRPOS(email, '@')) domain,
      SUBSTR(email, 1, STRPOS(email, '@') - 1) user
    FROM `project.dataset.table`  
  )
)
SELECT DISTINCT CONCAT(user, domain) email
FROM temp, UNNEST(
  (SELECT ARRAY_CONCAT_AGG([user1, user2]) 
    FROM UNNEST(users) user1, UNNEST(users) user2 
    WHERE user1 > user2
    AND (user1 = SUBSTR(user2, 1, LENGTH(user2) - 1)
    OR user2 = SUBSTR(user1, 1, LENGTH(user1) - 1))
  )
) user
WHERE ARRAY_LENGTH(users) > 1

с результатом

Row email    
1   samfake1@gmail.com   
2   samfake@gmail.com    
3   sarahshouse4@yahoo.com   
4   sarahshouse@yahoo.com      

Обновление по адресу> Быстрый вопрос, моя дата имеет тип отметки времени

используйте UNIX_DATE(DATE(dt)), затем

0 голосов
/ 27 сентября 2018

сопутствующий подзапрос, один приблизительный подход в случае уникального имени

select * from t
where exists ( select 1 from t t1 where t1.email like '%'+t.email+'%'
              and t1.date=t.date)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...