Создание пар ключ-значение из таблицы SQL

0

Недавно я столкнулся с проблемой, когда у меня было имя многих веб-сайтов в столбце (с повторениями), где мне приходилось выяснять домены, которые существуют как 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 идея, как я мог это сделать? Заранее спасибо.

  • 0
    Вопрос состоит в том, чтобы найти все домены, которые существуют как в https, так и в http форме. Я взял идею словаря от Python. (теперь я вижу, что это избыточно)
  • 0
    Вы работаете в MySQL или BigQuery? Вы пометили как ...
Теги:
google-bigquery

3 ответа

1
Лучший ответ

Использование 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
1

Хм это интересный вопрос; Я просто брошу свои 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) для этой задачи, я полагаю.

  • 0
    Ваш запрос выводит домены, в которых существуют только версии http. (В таблице o / p столбец http имеет значение true, а столбец https - false)
  • 0
    странно ... не знаю, почему это происходит. Данные, которые я смоделировал, также похожи на ваши. Если вы выполните этот запрос с имитированными данными, вы получите правильный результат?
Показать ещё 1 комментарий
0

Как насчет чего-то подобного? Таким образом, не так много корреляции между подзапросами.

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, что кажется сомнительным.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню