两个表
网站访问表:用户,请求次数,站点id,访问时间(每1小时相应用户、站点有一次记录)
网站与网站类型关系表:站点id,网站类型id   (两个id之间为n对n的关系)某个用户访问了多少种不同的站点,不同的站点类型,以及总共有多少次请求(就这里犯难了)
查询条件有:限制时间段,限制网站类型id在某个范围内
分组条件是:根据用户分组,到最后应该是每个用户对应了多少种不同的站点,不同的站点类型,不同的请求数曾经用过的方法:
SELECT count(distinct 站点id), count(distinct 网站类型id), sum(请求次数) from 网站访问表,关系表 where 网站访问表.站点id=关系表.站点id AND 关系表.网站类型id in (范围) AND 请求时间;这个结果就是 站点数,网站类型数都对,但是请求次数那错了,由于cross join,一个站点对应多个站点类型,而产生了重复的数据请教高人指教我应该怎么在这一条语句中再拿到一个用户在这个时段内正确的请求次数,谢谢!

解决方案 »

  1.   

    上面的查询语句稍微改一下:
    SELECT 用户,count(distinct 站点id), count(distinct 网站类型id), sum(请求次数) from 网站访问表,关系表 where 网站访问表.站点id=关系表.站点id AND 关系表.网站类型id in (范围) AND 请求时间
    GROUP BY 用户;网站访问表:
    用户,请求次数,站点id,访问时间
    用户1    5       3      12345
    网站关系表:
    站点id,网站类型id
    3       1
    3       2
    查找结果为:
    用户,站点数,类型数,总请求数
    用户1    1      2        10就是总请求数这里出问题了……
      

  2.   

     (不要高估你的汉语表达能力或者我的汉语理解能力)
       建议你列出你的表结构,并提供测试数据以及基于这些测试数据的所对应正确结果。
       参考一下这个贴子的提问方式http://topic.csdn.net/u/20091130/20/8343ee6a-417c-4c2d-9415-fa46604a00cf.html
       
       1. 你的 create table xxx .. 语句
       2. 你的 insert into xxx ... 语句
       3. 结果是什么样,(并给以简单的算法描述)
       4. 你用的数据库名称和版本(经常有人在MS SQL server版问 MySQL)
       
       这样想帮你的人可以直接搭建和你相同的环境,并在给出方案前进行测试,避免文字描述理解上的误差。   
      

  3.   

    哦,抱歉~~
    DROP TABLE IF EXISTS table_log_site;
    CREATE TABLE table_log_site(
    m_date INTEGER,
    m_requests INTEGER,
    m_accepts INTEGER,
    site_id INTEGER,
    user_id INTEGER
    );DROP TABLE IF EXISTS table_sites_type_urls;
    CREATE TABLE table_sites_type_urls(
    site_id INTEGER,
    sites_type_id INTEGER
    );INSERT INTO table_log_site(m_date, m_requests, m_accepts, site_id, user_id) 
    VALUES
    (123456, 4, 3, 1, 1),
    (123456, 5, 4, 2, 1),
    (123456, 6, 5, 1, 2),
    (123456, 7, 6, 2, 2);
    INSERT INTO table_sites_type_urls(site_id, sites_type_id) 
    VALUES 
    (1, 2),
    (1, 3),
    (2, 4),
    (2, 5);select count(distinct table_sites_type_urls.sites_type_id) as total_sites_type,sum(table_log_site.m_requests) as total_request , user_id from table_log_site,table_sites_type_urls where table_log_site.site_id=table_sites_type_urls.site_id group by table_log_site.user_id;+------------------+---------------+---------+
    | total_sites_type | total_request | user_id |
    +------------------+---------------+---------+
    |                4 |            18 |       1 |
    |                4 |            26 |       2 |
    +------------------+---------------+---------+就是这个语句中的total_request由于cross join出了问题。我希望能得到一个9,一个13
      

  4.   


    哦,抱歉~~
    DROP TABLE IF EXISTS table_log_site;
    CREATE TABLE table_log_site(
    m_date INTEGER,
    m_requests INTEGER,
    m_accepts INTEGER,
    site_id INTEGER,
    user_id INTEGER
    );DROP TABLE IF EXISTS table_sites_type_urls;
    CREATE TABLE table_sites_type_urls(
    site_id INTEGER,
    sites_type_id INTEGER
    );INSERT INTO table_log_site(m_date, m_requests, m_accepts, site_id, user_id) 
    VALUES
    (123456, 4, 3, 1, 1),
    (123456, 5, 4, 2, 1),
    (123456, 6, 5, 1, 2),
    (123456, 7, 6, 2, 2);
    INSERT INTO table_sites_type_urls(site_id, sites_type_id) 
    VALUES 
    (1, 2),
    (1, 3),
    (2, 4),
    (2, 5);select count(distinct table_sites_type_urls.sites_type_id) as total_sites_type,sum(table_log_site.m_requests) as total_request , user_id from table_log_site,table_sites_type_urls where table_log_site.site_id=table_sites_type_urls.site_id group by table_log_site.user_id;+------------------+---------------+---------+
    | total_sites_type | total_request | user_id |
    +------------------+---------------+---------+
    | 4 | 18 | 1 |
    | 4 | 26 | 2 |
    +------------------+---------------+---------+就是这个语句中的total_request由于cross join出了问题。我希望能得到一个9,一个13
      

  5.   


    哦,抱歉~~
    DROP TABLE IF EXISTS table_log_site;
    CREATE TABLE table_log_site(
    m_date INTEGER,
    m_requests INTEGER,
    m_accepts INTEGER,
    site_id INTEGER,
    user_id INTEGER
    );DROP TABLE IF EXISTS table_sites_type_urls;
    CREATE TABLE table_sites_type_urls(
    site_id INTEGER,
    sites_type_id INTEGER
    );INSERT INTO table_log_site(m_date, m_requests, m_accepts, site_id, user_id) 
    VALUES
    (123456, 4, 3, 1, 1),
    (123456, 5, 4, 2, 1),
    (123456, 6, 5, 1, 2),
    (123456, 7, 6, 2, 2);
    INSERT INTO table_sites_type_urls(site_id, sites_type_id) 
    VALUES 
    (1, 2),
    (1, 3),
    (2, 4),
    (2, 5);select count(distinct table_sites_type_urls.sites_type_id) as total_sites_type,sum(table_log_site.m_requests) as total_request , user_id from table_log_site,table_sites_type_urls where table_log_site.site_id=table_sites_type_urls.site_id group by table_log_site.user_id;+------------------+---------------+---------+
    | total_sites_type | total_request | user_id |
    +------------------+---------------+---------+
    | 4 | 18 | 1 |
    | 4 | 26 | 2 |
    +------------------+---------------+---------+就是这个语句中的total_request由于cross join出了问题。我希望能得到一个9,一个13
      

  6.   

    mysql> select * from table_log_site;
    +--------+------------+-----------+---------+---------+
    | m_date | m_requests | m_accepts | site_id | user_id |
    +--------+------------+-----------+---------+---------+
    | 123456 |          4 |         3 |       1 |       1 |
    | 123456 |          5 |         4 |       2 |       1 |
    | 123456 |          6 |         5 |       1 |       2 |
    | 123456 |          7 |         6 |       2 |       2 |
    +--------+------------+-----------+---------+---------+
    4 rows in set (0.00 sec)mysql> select * from table_sites_type_urls;
    +---------+---------------+
    | site_id | sites_type_id |
    +---------+---------------+
    |       1 |             2 |
    |       1 |             3 |
    |       2 |             4 |
    |       2 |             5 |
    +---------+---------------+
    4 rows in set (0.00 sec)mysql> select user_id,sum(m_requests) as total_request,
        ->  (select count(*)
        ->          from table_sites_type_urls a inner join table_log_site b using(site_id)
        ->          where b.user_id=t.user_id
        ->  ) as total_sites_type
        -> from table_log_site t
        -> group by user_id;
    +---------+---------------+------------------+
    | user_id | total_request | total_sites_type |
    +---------+---------------+------------------+
    |       1 |             9 |                4 |
    |       2 |            13 |                4 |
    +---------+---------------+------------------+
    2 rows in set (0.00 sec)mysql>
      

  7.   

    SELECT a.user_id,SUM(DISTINCT a.m_requests ),COUNT(*)
    FROM table_log_site a LEFT JOIN table_sites_type_urls b ON a.site_id=b.site_id
    GROUP BY a.user_id
      

  8.   


    呵呵,谢谢~~那如果我想通过sites_type_id(一个用“,”隔开的字符串,比如就用变量given_sites_type_str)来限制site_id,那我应该在后面再加个EXISTS (SELECT site_id FROM table_sites_type_urls WHERE site_id=t.site_id AND sites_type_urls IN(given_sites_type_str) limit 1)吧?通过 prepare statement from str的方式
      

  9.   


    这个只能在m_requests都不相同的时候才可以,如果有相同的,就会被归并的
      

  10.   

    SELECT a.user_id,SUM(DISTINCT a.m_requests ),COUNT(*)
    FROM table_log_site a LEFT JOIN table_sites_type_urls b ON a.site_id=b.site_id
    where find_in_set(given_sites_type_str,sites_type_urls)>0
    GROUP BY a.user_id
      

  11.   

    这个只能在m_requests都不相同的时候才可以,如果有相同的,就会被归并的……