I had to combine some of the previous answers , plus a little more hackery for my data set . This is what works for me , it returns the domain and any sub-domains:
SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(target_url, "https://stackoverflow.com/", 3), '://', -1), "https://stackoverflow.com/", 1), '?', 1) AS domain
Explanation ( cause non-trivial SQL rarely makes sense ):
SUBSTRING_INDEX(target_url, "https://stackoverflow.com/", 3) – strips any path if the url has a protocol
SUBSTRING_INDEX(THAT, '://', -1) – strips any protocol from THAT
SUBSTRING_INDEX(THAT, "https://stackoverflow.com/", 1) – strips any path from THAT ( if there was no protocol )
SUBSTRING_INDEX(THAT, '?', 1) – strips the query string from THAT ( if there was no path or trailing / )
Test Cases:
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(target_url, "https://stackoverflow.com/", 3), '://', -1), "https://stackoverflow.com/", 1), '?', 1) AS domain
FROM (
SELECT 'http://test.com' as target_url
UNION SELECT 'https://test.com'
UNION SELECT 'http://test.com/one'
UNION SELECT 'http://test.com/?huh'
UNION SELECT 'http://test.com?http://ouch.foo'
UNION SELECT 'test.com'
UNION SELECT 'test.com/one'
UNION SELECT 'test.com/one/two'
UNION SELECT 'test.com/one/two/three'
UNION SELECT 'test.com/one/two/three?u=http://maaaaannn'
UNION SELECT 'http://one.test.com'
UNION SELECT 'one.test.com/one'
UNION SELECT 'two.one.test.com/one' ) AS Test;
Results:
'test.com'
'test.com'
'test.com'
'test.com'
'test.com'
'test.com'
'test.com'
'test.com'
'test.com'
'test.com'
'one.test.com'
'one.test.com'
'two.one.test.com'