计算第一次出现外键

时间:2012-05-28 21:00:52

标签: php mysql

除了标签之外,如果可能的话,我想在查询中解决这个问题。 我有这张桌子

activity_type | value | date       | company_id
network.new   | 1     | 2011-10-08 | 1
members.count | 3     | 2011-10-08 | 1
network.new   | 1     | 2011-10-10 | 2
network.new   | 1     | 2011-10-11 | 3
members.count | 4     | 2011-10-11 | 2
  • 这基本上是一个日志活动。
  • 'network.new'活动仅发生 每个company_id
  • 一次
  • 'members_count'活动仅在以后发生 'network.new'出现在每个company_id上,并且每天可以出现一次 COMPANY_ID。

我需要制作一个折线图,X轴是日期,Y轴是两件事的数量:

  1. 第一次有多少个company_ids成员每天都有成员 时间(那是给我带来困难的那一次);
  2. 有多少人拥有network.new活动,只有那个活动 对于每一天。
  3. 我尝试的所有查询都给了我假阳性列表,主要是因为它会计算每天都有'members_count'活动的company_ids。

    如果可能,我希望创建一个查询,为create view目的提供date,first_time_members,new_company列。 我希望我的问题足够清楚,而且不是愚蠢的,因为我无法找到任何与我的问题相近的东西。

    [编辑]

    由于我的英语很差,我无法说清楚我会尝试更多地解释一下:

      

    我的客户有一个公司网络,他希望了解多少   公司日复一日地加入网络,但有一个问题:公司   登录网络时,它只被视为已完成   一个当它也有注册会员。所以他想知道,有多少   公司进行“不完整”注册,有多少人制作“完整”   报名。

    奥利琼斯先生让我朝着正确的方向前进,我想我可以利用他对我的强硬态度,但现在还没有。 顺便问一下,感谢ollie Jones的回答。像你这样的答案让我喜欢这个网站。

2 个答案:

答案 0 :(得分:1)

我要伸出脖子,猜猜你想要什么。您要求的是“第一次有多少个company_ids会员每天都有会员”。尊重,这是一个非常难以理解的陈述。

我认为你的意思是这样:对于每一天,在network.new活动类型中第一次出现多少个company_id值,并且在同一天有多少个伴随非零成员项目,并且有多少不是?

这是你做的:

首先想一个查询,它将为您系统中出现的每个公司提供第一个日期。试试这个。

SELECT MIN(date) networknewdate, company_id
  FROM table
 WHERE activity_type = 'network.new'
 GROUP BY company_id

这会产生一个networknewdate的虚拟表,company_id。

接下来,您需要一个查询,该查询将为每个公司提供member.count项目的第一个日期。

   SELECT MIN(date) memberscountdate, company_id
     FROM table
    WHERE activity_type = 'members.count'
    GROUP BY date

好的,现在我们有两个漂亮的虚拟表,每个最多只有一行为每个company_id值。让我们加入他们,推动第一个(network.new)值的加入。

  SELECT a.networknewdate, 
         a.company_id,
         IFNULL(b.members_present, 'no') members
    FROM (
      SELECT MIN(date) networknewdate, company_id
        FROM table
       WHERE activity_type = 'network.new'
       GROUP BY company_id
    ) a
    LEFT JOIN (
     SELECT MIN(date) memberscountdate, company_id, 'yes' members_present
       FROM table
      WHERE activity_type = 'members.count'
      GROUP BY date
    ) b ON (a.networknewdate = b.memberscountdate and a.company_id = b.company_id)

这将返回三列:日期,一个company_id,以及'yes'或'no',表示在同一天是否有第一个members.count记录,每个company_id的第一个network.new记录。

现在你需要总结这整件事情,这样你每天就能获得一条记录,其中列出了“是”的数量和“否”项的数量。我们走了。

白天的“是”记录数。

SELECT networknewdate, count(*) yesrecords
  FROM (
      SELECT a.networknewdate, 
             a.company_id,
             IFNULL(b.members_present, 'no') members
        FROM (
          SELECT MIN(date) networknewdate, company_id
            FROM table
           WHERE activity_type = 'network.new'
           GROUP BY company_id
        ) a
        LEFT JOIN (
         SELECT MIN(date) memberscountdate, company_id, 'yes' members_present
           FROM table
          WHERE activity_type = 'members.count'
          GROUP BY date
        ) b ON (a.networknewdate = b.memberscountdate and a.company_id = b.company_id)
     ) r
 WHERE r.members = 'yes'
 GROUP BY networknewdate

按日期没有记录的数量是类似的查询。然后你需要在networknewdate上将这两个查询一起加入,这样你就可以获得一个日期表,是的记录,norecords。我打算把这个作为一个切割粘贴练习给你。这是我在GROUP BY networknewdate结尾的查询的两倍多。

欢迎使用实现真实业务逻辑的SQL!我认为这个问题的主要教训是,你要求的结果实际上很难指定。一旦你准确地指定了你想要的东西,写一个查询来获得它是乏味和重复但不难。

另一个小提示。您可以创建一些视图,这样您的查询就不那么庞大了。

答案 1 :(得分:1)

所以使用相同的方法,Ollie jones向我展示了我的想法: 首先,我需要一个日期列表,其中'members_count'或'network.new'发生

SELECT date as current_date
FROM activity_log ld
WHERE `activity_type` in ('members_count', 'network.new')
GROUP BY date
ORDER BY date

我离开加入了一个首日期公司名单

SELECT MIN(date) AS new_date, company_id
FROM activity_log
WHERE activity_type =  'network.new'
GROUP BY company_id
ORDER BY date

也是第一次加入公司会员

    SELECT min(date) as members_count_date, company_id 
FROM `activity_networks` WHERE `activity_type` = 'network.daily.members_count'
GROUP BY company_id 
ORDER BY date

然后a按照日期分组,对第一次计算成员的新公司和公司进行明确计算。然后我有这个:

    SELECT DATE(FROM_UNIXTIME(ld.date)) as curr_date,
COUNT(DISTINCT(new_co)) as new_co,
COUNT(DISTINCT(complete_co)) as complete
FROM activity_log ld 
LEFT JOIN (SELECT date AS new_date, company_id as new_co
FROM activity_networks
WHERE activity_type =  'network.new'
GROUP BY company_id
ORDER BY date) nd ON (ld.date=nd.new_date)
LEFT JOIN (SELECT min(date) as members_count_date, company_id as complete_co
FROM `activity_log` WHERE `activity_type` = 'members_count'
GROUP BY company_id 
ORDER BY date) mcd ON (mcd.members_count_date=ld.date)
WHERE `activity_type` in ('members_count', 'network.new')
GROUP BY DATE(FROM_UNIXTIME(ld.date))
ORDER BY ld.date

独特的功能至关重要,因为没有它,计数就没有了。它并不完美。我名为'new_co'的列应该只带来不完整的注册(不完整的方式,新注册的成员链接到公司),但信息仍然有用。