MySQL查询 - 优化

时间:2012-04-02 22:42:25

标签: mysql sql select join

是否可以通过一个 MySQL 查询来实现此任务?

网址。字段{ ID 网址}

1,www.mysite.kom
2,mysite.kom
3,anothersite.kom

日志。字段{ ID url_id group_type - 数字范围为1..10}

1,1,4 2,1,4 3,2,5 4,2,5
5,3,9

此示例中的查询结果应为: 1 (mysite.com和www.mysite.com = 1)

目标:

需要统计日志表中记录的所有不同网址,但有几个条件:

1)包含 www。前缀的网址,如 mysite.kom www.mysite.kom ,被视为 1 (不是2)。

2) group_type 的范围为 4..6

3)现在,任何这些 group_type 4..6 的网址都会被忽略,而不会显示在 group_type 低于4的网址列表中完全算了。

SQL代码:

SELECT COUNT(DISTINCT TRIM(LEADING 'www.' FROM b.url))
FROM logs a
INNER JOIN urls b
ON a.url_id = b.id
WHERE (group_type BETWEEN 4 AND 6) 

----- and this condition below -----

AND TRIM(LEADING 'www.' FROM b.url)
NOT IN (
  SELECT TRIM(LEADING 'www.' FROM b.url)
  FROM logs a
  INNER JOIN urls b
  ON a.url_id = b.id
  WHERE (group_type < 4)
)

如果我的sql查询是正确的,可以优化(看起来更紧凑)吗?

2 个答案:

答案 0 :(得分:3)

SELECT COUNT(DISTINCT u.id) AS COUNT_QUES FROM urls u
INNER JOIN logs l
ON u.id=l.url_id
WHERE u.url NOT IN (SELECT A.url FROM 
(SELECT * FROM urls u
WHERE SUBSTR(u.url,1,3)!='www')A,
(SELECT * FROM urls v
WHERE SUBSTR(v.url,1,3)='www')B
WHERE A.url=SUBSTR(B.url,5,LENGTH(B.url))
) 
AND l.group_type BETWEEN 4 AND 6
AND u.id NOT IN
(SELECT DISTINCT u.id FROM urls u
INNER JOIN logs l
ON u.id=l.url_id
WHERE u.url NOT IN (SELECT A.url FROM 
(SELECT * FROM urls u
WHERE SUBSTR(u.url,1,3)!='www')A,
(SELECT * FROM urls v
WHERE SUBSTR(v.url,1,3)='www')B
WHERE A.url=SUBSTR(B.url,5,LENGTH(B.url))
) 
AND l.group_type < 4
)

OR

SELECT COUNT(DISTINCT CASE WHEN B.URL_ID IS NOT NULL AND FLAG1 = 1 AND FLAG2 = 0 THEN TRIM(LEADING 'www.' FROM A.URL) END)
FROM URLS A 
LEFT JOIN (SELECT URL_ID,
           MAX(CASE WHEN GROUP_TYPE BETWEEN 4 AND 6 THEN 1 ELSE 0 END) FLAG1,
           MAX(CASE WHEN GROUP_TYPE < 4 THEN 1 ELSE 0 END) FLAG2
           FROM LOGS
           GROUP BY URL_ID) B
           ON A.ID = B.URL_ID

希望这对您有用。请在SQLFIDDLE上查看 - http://sqlfiddle.com/#!2/1fde2/39

答案 1 :(得分:1)

这是一种方式:

SELECT trimmed_url
  FROM ( SELECT TRIM(LEADING 'www.' FROM urls.url) AS trimmed_url,
                MIN(logs.group_type) AS min_group_type
           FROM logs
           JOIN urls
             ON urls.id = logs.url_id
          GROUP
             BY trimmed_url
       ) t
 WHERE min_group_type BETWEEN 4 AND 6
;

但只有你可以判断它是否看起来更紧凑,只有测试可以判断它是否表现更好。