Недавно я столкнулся с проблемой, когда у меня было имя многих веб-сайтов в столбце (с повторениями), где мне приходилось выяснять домены, которые существуют как http и https (например: https://www.google.com и http://www.google.com). Запрос, который я сделал, был -
'SELECT distinct SPLIT(origin,"://")[OFFSET(1)] as domain
FROM "chrome-ux-report.chrome_ux_report.201710" x
WHERE SPLIT(x.origin,"://")[OFFSET(0)] = "http"
and SPLIT(x.origin,"://")[OFFSET(1)] in
(SELECT SPLIT(y.origin,"://")[OFFSET(1)]
FROM "chrome-ux-report.chrome_ux_report.201710" y
WHERE SPLIT(y.origin,"://")[OFFSET(0)] = "https" )
ORDER BY domain'
Этот запрос занимает время O (n ^ 2). Зная python, я не мог не подумать о решении, где я мог бы создать новую таблицу с доменом как ключом, а http и https - как значения, например dict ['www.google.com'] = [1,1 ] или в sql -
Domain http https
www.google.com 1 1
который будет принимать O (n) time.Any идея, как я мог это сделать? Заранее спасибо.
Использование Common Table Expression для предварительного выбора данных должно сократить много этого O (n ^ 2). Не для O (n), а гораздо ближе.
WITH cte AS (
SELECT DISTINCT origin
FROM "chrome-ux-report.chrome_ux_report.201710" x
WHERE SPLIT(x.origin,"://")[OFFSET(0)] IN ("http", "https")
)
SELECT DISTINCT SPLIT(origin,"://")[OFFSET(1)] AS domain
FROM cte
WHERE SPLIT(cte.origin,"://")[OFFSET(0)] = "http"
AND SPLIT(cte.origin,"://")[OFFSET(1)] IN (
SELECT SPLIT(cte2.origin,"://")[OFFSET(1)]
FROM cte AS cte2
WHERE SPLIT(cte2.origin,"://")[OFFSET(0)] = "https"
)
ORDER BY domain
Хм это интересный вопрос; Я просто брошу свои 2 цента. Вот как я решил бы это в BigQuery:
WITH data AS(
SELECT 'http://google.com.br' AS origin UNION ALL
SELECT 'https://google.com.br' AS origin UNION ALL
SELECT 'https://www.google.com.br' UNION ALL
SELECT 'http://domain1' UNION ALL
SELECT 'https://domain2'
)
SELECT
REGEXP_EXTRACT(origin, r'://(.*)') AS domain,
MAX(IF(REGEXP_CONTAINS(origin, r'^http[^s]'), TRUE, FALSE)) http,
MAX(IF(REGEXP_CONTAINS(origin, r'^https'), TRUE, FALSE)) https
FROM data
GROUP BY 1
Результаты:
Row domain http https
1 www.google.com.br false true
2 domain2 false true
3 google.com.br true true
4 domain1 true false
BigO для этого запроса, я полагаю, ниже n^2
но он, вероятно, больше n
: в MySQL индексированный столбец AFAIK может сделать поиск строки в log(n)
(предположим дерево b-index) и, поскольку это происходит n
раз в этом запросе, поэтому конечным результатом является nlog(n)
.
(возможно, использовать Hash Maps для достижения O(n)
но я не знаю, будет ли конечный результат n
)
BigQuery, с другой стороны, не имеет индексации; он имеет разные стратегии управления данными, как вы можете видеть в этом сообщении (удивительное чтение).
Тем не менее, возможно, BigQuery не может достичь O(n)
для этой задачи, я полагаю.
Как насчет чего-то подобного? Таким образом, не так много корреляции между подзапросами.
Select sum(if(origin like 'http://%', 1,0 ) as http,
sum(if(origin like 'https://%', 1,0 ) as https,
Replace(Replace (origin,'http://',''),'https://','') as domain
Group by domain
Предполагая, что вы действительно хотите MySQL, что кажется сомнительным.