【问题标题】:SELECT to pick users who both viewed a pageSELECT 选择同时查看页面的用户
【发布时间】:2010-01-29 03:24:16
【问题描述】:

我有一个记录每个用户的页面浏览量的表格:

+--------------+--------------+------+-----+---------+----------------+
| Field        | Type         | Null | Key | Default | Extra          |
+--------------+--------------+------+-----+---------+----------------+
| view_id      | int(11)      | NO   | PRI | NULL    | auto_increment | 
| page_id      | int(11)      | YES  | MUL | NULL    |                | 
| user_id      | int(11)      | YES  | MUL | NULL    |                | 
+--------------+--------------+------+-----+---------+----------------+

对于每一对用户,我想生成一个他们都看过多少页的计数。

我根本不知道该怎么做。 :) 我正在使用 mysql,以防它有一个非标准的功能,让这变得轻而易举。

【问题讨论】:

  • 您想对每一对可能的配对都这样做吗?这可能是很多结果,我认为准确地说是 (n^2-n)/2。
  • 您想要所有用户组合吗?如果你有 1000 个用户,1000 选择 2 = 499 500,10000 用户:10000 选择 2 = 49 995 000 ... >___>
  • @Lukman,我不确定我明白你的意思。
  • 他的意思是,如果根据基础数学,你会得到很多结果。 3 个用户给出 3 行,但 4 个用户给出 6 个,5 个给出 10 个,1000 个给出近 50 万行,10000 个给出近 5000 万行。这样的查询很容易损害您的系统。

标签: sql mysql database select


【解决方案1】:
select u1.user_id, u2.user_id, count(distinct u1.page_id) as NumPages
from logtable u1
  join
  logtable u2
  on u1.page_id = u2.page_id
  and u1.user_id < u2.user_id /* This avoids counting pairs twice */
group by u1.user_id, u2.user_id;

但是你应该考虑过滤一下...

(上面编辑放了u1.page_id,原来只是page_id,真的很讨厌我)

【讨论】:

  • @Rob,谢谢!经过一些简短的测试,这似乎完全符合我的要求。请注意:mysql 抱怨 page_id 不明确,因此我将 [following Tor below] 'count(distinct page_id)' 替换为 'count(distinct u1.page_id)'。非常感谢。 :)
  • @Rob,我点击错误并删除了我之前的投票。为了让我能够将其添加回来,您需要对您的答案进行一些小的编辑(添加一个词左右?)。 :)
  • @Rob,再次感谢您的回答。 :) 我得到一个只包含 300k 记录的结果集。对于 10k 个不同的用户,我期待一个更大的表 [(10k**2-10k)/2) ~ 55m 记录]。由于没有报告 NumPages=0 的对,我猜测该查询仅列出共享至少一页的那些对 - 这是正确的吗?还是我做错了什么?
  • 没错。联接仅考虑具有共同页面的用户对。
【解决方案2】:
SELECT DISTINCT page_id
FROM logtable
WHERE user_id = 1 OR user_id = 2
GROUP BY page_id
HAVING COUNT(DISTINCT user_id) = 2

此表返回他们都看过的所有页面。如果您想要计数,则只需将其设为子查询并计算行数。

SELECT COUNT(*) FROM (the query above) s;

更新,让我们为所有用户对进行更新。

SELECT u1.user_id, u2.user_id, COUNT(DISTINCT u1.page_id)
FROM logtable u1, logtable u2
WHERE u1.user_id < u2.user_id
  AND u1.page_id = u2.page_id
GROUP BY u1.user_id, u2.user_id

【讨论】:

  • 你确定你在回答这个问题吗?
  • OP 希望看到两个用户都查看的页面。
  • 这并没有解决“每对用户”的问题,对吧?
  • @Rob - 正确,但我从来没有看到这样做的用途...... OP 听起来像是对特定情况的查找,例如“你有多少共同点和这个人”之类的事情。
  • 不,但我可以想象类似“是否有其他用户与用户 123 访问了很多相同的页面?”。
【解决方案3】:

对于 users_ids 100 和 200。

SELECT
  page_id
FROM table1
WHERE user_id IN (100, 200)
GROUP BY page_id
HAVING MAX(CASE WHEN user_id = 100 THEN 1 ELSE 0 END) = 1
  AND MAX(CASE WHEN user_id = 200 THEN 1 ELSE 0 END) = 1;

【讨论】:

    【解决方案4】:
    select a.user_id as user1, b.user_id as user2, count(distinct a.page_id) as views
    from yourtable a, yourtable b
    where a.page_id = b.page_id 
    and a.user_id < b.user_id
    group by a.user_id, b.user_id
    

    yourtable 更改为您的表的名称..

    【讨论】:

    • count(*) 在这里不起作用,因为用户可能会重复访问同一页面。如果他们都访问过一个页面 3 次,则该页面会被计算太多次。如果表格只记录每个页面的第一次访问,那么就可以了。
    • @Rob: 使用 count(distinct a.page_id) 修复
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-23
    • 1970-01-01
    • 2016-03-31
    • 2013-04-13
    • 2023-01-24
    • 2010-09-17
    • 1970-01-01
    相关资源
    最近更新 更多