Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/238.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 从一个表中获取另一个表中不存在的记录_Php_Mysql_Group By_Unix Timestamp - Fatal编程技术网

Php 从一个表中获取另一个表中不存在的记录

Php 从一个表中获取另一个表中不存在的记录,php,mysql,group-by,unix-timestamp,Php,Mysql,Group By,Unix Timestamp,我知道标题听起来好像已经有几十个类似的问题,但我认为这一个有点不同。不过,如果已经有一个类似的问题,请告诉我 基本上,我有两个表:用户和简历。下面是他们的模式片段: users: id signup_time resumes: id user_id modified_time 现在,我需要获取在用户指定的时间范围内(所有日期都是UNIX时间戳)没有简历的所有用户的总数,一般来说,当他们没有上传简历时,按天、周或月进行分组。这是最让我困扰的问题,因为如果不是分组,查询可能会

我知道标题听起来好像已经有几十个类似的问题,但我认为这一个有点不同。不过,如果已经有一个类似的问题,请告诉我

基本上,我有两个表:
用户
简历
。下面是他们的模式片段:

users:
    id  signup_time
resumes:
    id  user_id  modified_time
现在,我需要获取在用户指定的时间范围内(所有日期都是UNIX时间戳)没有简历的所有用户的总数,一般来说,当他们没有上传简历时,按天、周或月进行分组。这是最让我困扰的问题,因为如果不是分组,查询可能会如下所示:

SELECT u.id FROM `jb_users` u WHERE
    u.id NOT IN (
        SELECT r.user_id FROM `jb_resumes` r
        WHERE (r.modified_time BETWEEN 1330581600 AND 1335848399)
    ) AND u.signup_time >= 1330581600
例如,让我们考虑一些例子。希望这样更容易理解

假设我们有数据:

users
    id  signup_time
    ---------------
    1   1340214369 (20.06.2012)
    2   1330754400 (03.03.2012)
    3   1329285600 (15.02.2012)
    4   1324447200 (21.12.2011)
resumes
    id  user_id  modified_time
    --------------------------
    1   1        1340214369 (20.06.2012)
    2   2        1330840800 (04.03.2012)
    3   2        1340214369 (20.06.2012)
    4   3        1334506920 (15.04.2012)
    5   3        1334638800 (17.04.2012)
    6   2        1334638800 (17.04.2012)
    7   3        1336798800 (12.05.2012)
对于时间范围2012年3月1日00:00:00-2012年4月30日23:59:59(按月份分组),应返回:

count   user_ids    time
2       3,4         1330840800 (03.2012 - can be any date in the month, in fact)
1       4           1334506920 (04.2012 - can be any date in the month, in fact)
count   user_ids    time
2       3,4         1330840800 (04.03.2012)
2       2,4         1334506920 (15.04.2012)
1       4           1334638800 (17.04.2012)
对于相同的时间段,但每天分组,它应该返回:

count   user_ids    time
2       3,4         1330840800 (03.2012 - can be any date in the month, in fact)
1       4           1334506920 (04.2012 - can be any date in the month, in fact)
count   user_ids    time
2       3,4         1330840800 (04.03.2012)
2       2,4         1334506920 (15.04.2012)
1       4           1334638800 (17.04.2012)
我希望这个问题足够清楚。如果没有,请告诉我

数据将使用PHP进行处理,因此,如果无法使用单个查询(即使是子查询)实现这一点,也可以使用PHP处理数据

谢谢。

试试这个:

   SELECT count(u.id) FROM `jb_users` u WHERE
        u.id NOT IN (
            SELECT distinct r.user_id FROM `jb_resumes` r
            WHERE (r.modified_time BETWEEN 1330581600 AND 1335848399)
 ) AND u.signup_time >= 1330581600 GROUP BY FROM_UNIXTIME(u.signup_time) ORDER BY u.signup_time
将unix时间戳返回为日期格式

它将按日期返回特定时间范围组内的总用户数。您可以根据需要转换日期格式

我在内部选择查询中添加了DISTINCT关键字,因为一个用户可以多次更新简历,否则您也可以获得不在该日期范围内的记录。

尝试以下操作:

   SELECT count(u.id) FROM `jb_users` u WHERE
        u.id NOT IN (
            SELECT distinct r.user_id FROM `jb_resumes` r
            WHERE (r.modified_time BETWEEN 1330581600 AND 1335848399)
 ) AND u.signup_time >= 1330581600 GROUP BY FROM_UNIXTIME(u.signup_time) ORDER BY u.signup_time
将unix时间戳返回为日期格式

它将按日期返回特定时间范围组内的总用户数。您可以根据需要转换日期格式


我在内部选择查询中添加了DISTINCT关键字,因为一个用户可以多次更新resume,否则您也可以获得不在该日期范围内的记录。

不确定这是否有效,但您可以尝试使用if进行连接

SELECT DISTINCT
if(r.modified_time NOT BETWEEN 1330581600 AND 1335848399, u.id, null) as UID
FROM `jb_users` u 
Left Join `jb_resumes` r ON u.id = r.user_id
WHERE
u.signup_time >= 1330581600

不确定这是否有效,但您可以尝试使用if进行连接

SELECT DISTINCT
if(r.modified_time NOT BETWEEN 1330581600 AND 1335848399, u.id, null) as UID
FROM `jb_users` u 
Left Join `jb_resumes` r ON u.id = r.user_id
WHERE
u.signup_time >= 1330581600

下面是我提出的按月份分组的解决方案。我在本地MySQL安装中使用了您的数据来测试结果:

SELECT 
    COUNT(*) AS cnt,
    GROUP_CONCAT(b.id ORDER BY b.id) AS user_ids,
    a.monthgroup

FROM 
(
    SELECT MONTH(FROM_UNIXTIME(modified_time)) AS monthgroup
    FROM jb_resumes
    WHERE modified_time BETWEEN 
        UNIX_TIMESTAMP('2012-03-01 00:00:00') 
        AND UNIX_TIMESTAMP('2012-04-30 23:59:59')
    GROUP BY monthgroup
) a
CROSS JOIN 
    jb_users b
LEFT JOIN
    jb_resumes c ON 
        b.id = c.user_id 
        AND a.monthgroup = MONTH(FROM_UNIXTIME(modified_time))
WHERE
    b.signup_time < UNIX_TIMESTAMP('2012-04-30 23:59:59')
    AND c.user_id IS NULL
GROUP BY
    a.monthgroup
ORDER BY
    a.monthgroup
导致:

然后为了比较每个
monthgroup
和每个用户的组合,找出哪些用户在
monthgroup
中没有修改时间,我们必须在
monthgroup
和所有用户之间进行笛卡尔积。由于上面的查询已经使用了一个
GROUP BY
,因此我们不能直接加入该查询,而是必须将其包装在
FROM
子句中的subselect中:

SELECT 
    a.monthgroup,
    b.*
FROM 
(
    SELECT MONTH(FROM_UNIXTIME(modified_time)) AS monthgroup
    FROM jb_resumes
    WHERE modified_time BETWEEN 
        UNIX_TIMESTAMP('2012-03-01 00:00:00') 
        AND UNIX_TIMESTAMP('2012-04-30 23:59:59')
    GROUP BY monthgroup
) a
CROSS JOIN 
    jb_users b
--
ORDER BY a.monthgroup, b.id #for clarity's sake
SELECT 
    a.monthgroup,
    b.*
FROM 
(
    SELECT MONTH(FROM_UNIXTIME(modified_time)) AS monthgroup
    FROM jb_resumes
    WHERE modified_time BETWEEN 
        UNIX_TIMESTAMP('2012-03-01 00:00:00') 
        AND UNIX_TIMESTAMP('2012-04-30 23:59:59')
    GROUP BY monthgroup
) a
CROSS JOIN 
    jb_users b
WHERE
    b.signup_time < UNIX_TIMESTAMP('2012-04-30 23:59:59')
--
ORDER BY a.monthgroup, b.id #for clarity's sake
SELECT 
    a.monthgroup,
    b.*,
    c.*
FROM 
(
    SELECT MONTH(FROM_UNIXTIME(modified_time)) AS monthgroup
    FROM jb_resumes
    WHERE modified_time BETWEEN 
        UNIX_TIMESTAMP('2012-03-01 00:00:00') 
        AND UNIX_TIMESTAMP('2012-04-30 23:59:59')
    GROUP BY monthgroup
) a
CROSS JOIN 
    jb_users b
LEFT JOIN
    jb_resumes c ON 
        b.id = c.user_id 
        AND a.monthgroup = MONTH(FROM_UNIXTIME(modified_time))
WHERE
    b.signup_time < UNIX_TIMESTAMP('2012-04-30 23:59:59')
    AND c.user_id IS NULL
--
ORDER BY a.monthgroup, b.id #for clarity's sake
导致:

现在我们有了
monthgroup
s和all
id
s的组合,但我们不想包括
signup\u时间晚于时间范围的用户,因此我们通过在
WHERE
子句中引入第一个条件来过滤它们:

SELECT 
    a.monthgroup,
    b.*
FROM 
(
    SELECT MONTH(FROM_UNIXTIME(modified_time)) AS monthgroup
    FROM jb_resumes
    WHERE modified_time BETWEEN 
        UNIX_TIMESTAMP('2012-03-01 00:00:00') 
        AND UNIX_TIMESTAMP('2012-04-30 23:59:59')
    GROUP BY monthgroup
) a
CROSS JOIN 
    jb_users b
--
ORDER BY a.monthgroup, b.id #for clarity's sake
SELECT 
    a.monthgroup,
    b.*
FROM 
(
    SELECT MONTH(FROM_UNIXTIME(modified_time)) AS monthgroup
    FROM jb_resumes
    WHERE modified_time BETWEEN 
        UNIX_TIMESTAMP('2012-03-01 00:00:00') 
        AND UNIX_TIMESTAMP('2012-04-30 23:59:59')
    GROUP BY monthgroup
) a
CROSS JOIN 
    jb_users b
WHERE
    b.signup_time < UNIX_TIMESTAMP('2012-04-30 23:59:59')
--
ORDER BY a.monthgroup, b.id #for clarity's sake
SELECT 
    a.monthgroup,
    b.*,
    c.*
FROM 
(
    SELECT MONTH(FROM_UNIXTIME(modified_time)) AS monthgroup
    FROM jb_resumes
    WHERE modified_time BETWEEN 
        UNIX_TIMESTAMP('2012-03-01 00:00:00') 
        AND UNIX_TIMESTAMP('2012-04-30 23:59:59')
    GROUP BY monthgroup
) a
CROSS JOIN 
    jb_users b
LEFT JOIN
    jb_resumes c ON 
        b.id = c.user_id 
        AND a.monthgroup = MONTH(FROM_UNIXTIME(modified_time))
WHERE
    b.signup_time < UNIX_TIMESTAMP('2012-04-30 23:59:59')
    AND c.user_id IS NULL
--
ORDER BY a.monthgroup, b.id #for clarity's sake
导致:

这里我们是
左加入
ing,条件是用户在
jb\u resume
中有一个简历修改,并且修改发生在
月组
值的月份内。如果用户当月没有修改简历,则
LEFT JOIN
返回表中值的
NULL
。我们需要那些条件不满足的用户,因此我们必须在
where
子句中添加第二个条件:

SELECT 
    a.monthgroup,
    b.*
FROM 
(
    SELECT MONTH(FROM_UNIXTIME(modified_time)) AS monthgroup
    FROM jb_resumes
    WHERE modified_time BETWEEN 
        UNIX_TIMESTAMP('2012-03-01 00:00:00') 
        AND UNIX_TIMESTAMP('2012-04-30 23:59:59')
    GROUP BY monthgroup
) a
CROSS JOIN 
    jb_users b
--
ORDER BY a.monthgroup, b.id #for clarity's sake
SELECT 
    a.monthgroup,
    b.*
FROM 
(
    SELECT MONTH(FROM_UNIXTIME(modified_time)) AS monthgroup
    FROM jb_resumes
    WHERE modified_time BETWEEN 
        UNIX_TIMESTAMP('2012-03-01 00:00:00') 
        AND UNIX_TIMESTAMP('2012-04-30 23:59:59')
    GROUP BY monthgroup
) a
CROSS JOIN 
    jb_users b
WHERE
    b.signup_time < UNIX_TIMESTAMP('2012-04-30 23:59:59')
--
ORDER BY a.monthgroup, b.id #for clarity's sake
SELECT 
    a.monthgroup,
    b.*,
    c.*
FROM 
(
    SELECT MONTH(FROM_UNIXTIME(modified_time)) AS monthgroup
    FROM jb_resumes
    WHERE modified_time BETWEEN 
        UNIX_TIMESTAMP('2012-03-01 00:00:00') 
        AND UNIX_TIMESTAMP('2012-04-30 23:59:59')
    GROUP BY monthgroup
) a
CROSS JOIN 
    jb_users b
LEFT JOIN
    jb_resumes c ON 
        b.id = c.user_id 
        AND a.monthgroup = MONTH(FROM_UNIXTIME(modified_time))
WHERE
    b.signup_time < UNIX_TIMESTAMP('2012-04-30 23:59:59')
    AND c.user_id IS NULL
--
ORDER BY a.monthgroup, b.id #for clarity's sake
给我们期望的结果:


以下是我提出的按月份分组的解决方案。我在本地MySQL安装中使用了您的数据来测试结果:

SELECT 
    COUNT(*) AS cnt,
    GROUP_CONCAT(b.id ORDER BY b.id) AS user_ids,
    a.monthgroup

FROM 
(
    SELECT MONTH(FROM_UNIXTIME(modified_time)) AS monthgroup
    FROM jb_resumes
    WHERE modified_time BETWEEN 
        UNIX_TIMESTAMP('2012-03-01 00:00:00') 
        AND UNIX_TIMESTAMP('2012-04-30 23:59:59')
    GROUP BY monthgroup
) a
CROSS JOIN 
    jb_users b
LEFT JOIN
    jb_resumes c ON 
        b.id = c.user_id 
        AND a.monthgroup = MONTH(FROM_UNIXTIME(modified_time))
WHERE
    b.signup_time < UNIX_TIMESTAMP('2012-04-30 23:59:59')
    AND c.user_id IS NULL
GROUP BY
    a.monthgroup
ORDER BY
    a.monthgroup
导致:

然后为了比较每个
monthgroup
和每个用户的组合,找出哪些用户在
monthgroup
中没有修改时间,我们必须在
monthgroup
和所有用户之间进行笛卡尔积。由于上面的查询已经使用了一个
GROUP BY
,因此我们不能直接加入该查询,而是必须将其包装在
FROM
子句中的subselect中:

SELECT 
    a.monthgroup,
    b.*
FROM 
(
    SELECT MONTH(FROM_UNIXTIME(modified_time)) AS monthgroup
    FROM jb_resumes
    WHERE modified_time BETWEEN 
        UNIX_TIMESTAMP('2012-03-01 00:00:00') 
        AND UNIX_TIMESTAMP('2012-04-30 23:59:59')
    GROUP BY monthgroup
) a
CROSS JOIN 
    jb_users b
--
ORDER BY a.monthgroup, b.id #for clarity's sake
SELECT 
    a.monthgroup,
    b.*
FROM 
(
    SELECT MONTH(FROM_UNIXTIME(modified_time)) AS monthgroup
    FROM jb_resumes
    WHERE modified_time BETWEEN 
        UNIX_TIMESTAMP('2012-03-01 00:00:00') 
        AND UNIX_TIMESTAMP('2012-04-30 23:59:59')
    GROUP BY monthgroup
) a
CROSS JOIN 
    jb_users b
WHERE
    b.signup_time < UNIX_TIMESTAMP('2012-04-30 23:59:59')
--
ORDER BY a.monthgroup, b.id #for clarity's sake
SELECT 
    a.monthgroup,
    b.*,
    c.*
FROM 
(
    SELECT MONTH(FROM_UNIXTIME(modified_time)) AS monthgroup
    FROM jb_resumes
    WHERE modified_time BETWEEN 
        UNIX_TIMESTAMP('2012-03-01 00:00:00') 
        AND UNIX_TIMESTAMP('2012-04-30 23:59:59')
    GROUP BY monthgroup
) a
CROSS JOIN 
    jb_users b
LEFT JOIN
    jb_resumes c ON 
        b.id = c.user_id 
        AND a.monthgroup = MONTH(FROM_UNIXTIME(modified_time))
WHERE
    b.signup_time < UNIX_TIMESTAMP('2012-04-30 23:59:59')
    AND c.user_id IS NULL
--
ORDER BY a.monthgroup, b.id #for clarity's sake
导致:

现在我们有了
monthgroup
s和all
id
s的组合,但我们不想包括
signup\u时间晚于时间范围的用户,因此我们通过在
WHERE
子句中引入第一个条件来过滤它们:

SELECT 
    a.monthgroup,
    b.*
FROM 
(
    SELECT MONTH(FROM_UNIXTIME(modified_time)) AS monthgroup
    FROM jb_resumes
    WHERE modified_time BETWEEN 
        UNIX_TIMESTAMP('2012-03-01 00:00:00') 
        AND UNIX_TIMESTAMP('2012-04-30 23:59:59')
    GROUP BY monthgroup
) a
CROSS JOIN 
    jb_users b
--
ORDER BY a.monthgroup, b.id #for clarity's sake
SELECT 
    a.monthgroup,
    b.*
FROM 
(
    SELECT MONTH(FROM_UNIXTIME(modified_time)) AS monthgroup
    FROM jb_resumes
    WHERE modified_time BETWEEN 
        UNIX_TIMESTAMP('2012-03-01 00:00:00') 
        AND UNIX_TIMESTAMP('2012-04-30 23:59:59')
    GROUP BY monthgroup
) a
CROSS JOIN 
    jb_users b
WHERE
    b.signup_time < UNIX_TIMESTAMP('2012-04-30 23:59:59')
--
ORDER BY a.monthgroup, b.id #for clarity's sake
SELECT 
    a.monthgroup,
    b.*,
    c.*
FROM 
(
    SELECT MONTH(FROM_UNIXTIME(modified_time)) AS monthgroup
    FROM jb_resumes
    WHERE modified_time BETWEEN 
        UNIX_TIMESTAMP('2012-03-01 00:00:00') 
        AND UNIX_TIMESTAMP('2012-04-30 23:59:59')
    GROUP BY monthgroup
) a
CROSS JOIN 
    jb_users b
LEFT JOIN
    jb_resumes c ON 
        b.id = c.user_id 
        AND a.monthgroup = MONTH(FROM_UNIXTIME(modified_time))
WHERE
    b.signup_time < UNIX_TIMESTAMP('2012-04-30 23:59:59')
    AND c.user_id IS NULL
--
ORDER BY a.monthgroup, b.id #for clarity's sake
导致:

这里我们是
左加入
ing,条件是用户在
jb\u resume
中有一个简历修改,并且修改发生在
月组
值的月份内。如果用户当月没有修改简历,则
LEFT JOIN
返回表中值的
NULL
。我们需要那些条件不满足的用户,因此我们必须在
where
子句中添加第二个条件:

SELECT 
    a.monthgroup,
    b.*
FROM 
(
    SELECT MONTH(FROM_UNIXTIME(modified_time)) AS monthgroup
    FROM jb_resumes
    WHERE modified_time BETWEEN 
        UNIX_TIMESTAMP('2012-03-01 00:00:00') 
        AND UNIX_TIMESTAMP('2012-04-30 23:59:59')
    GROUP BY monthgroup
) a
CROSS JOIN 
    jb_users b
--
ORDER BY a.monthgroup, b.id #for clarity's sake
SELECT 
    a.monthgroup,
    b.*
FROM 
(
    SELECT MONTH(FROM_UNIXTIME(modified_time)) AS monthgroup
    FROM jb_resumes
    WHERE modified_time BETWEEN 
        UNIX_TIMESTAMP('2012-03-01 00:00:00') 
        AND UNIX_TIMESTAMP('2012-04-30 23:59:59')
    GROUP BY monthgroup
) a
CROSS JOIN 
    jb_users b
WHERE
    b.signup_time < UNIX_TIMESTAMP('2012-04-30 23:59:59')
--
ORDER BY a.monthgroup, b.id #for clarity's sake
SELECT 
    a.monthgroup,
    b.*,
    c.*
FROM 
(
    SELECT MONTH(FROM_UNIXTIME(modified_time)) AS monthgroup
    FROM jb_resumes
    WHERE modified_time BETWEEN 
        UNIX_TIMESTAMP('2012-03-01 00:00:00') 
        AND UNIX_TIMESTAMP('2012-04-30 23:59:59')
    GROUP BY monthgroup
) a
CROSS JOIN 
    jb_users b
LEFT JOIN
    jb_resumes c ON 
        b.id = c.user_id 
        AND a.monthgroup = MONTH(FROM_UNIXTIME(modified_time))
WHERE
    b.signup_time < UNIX_TIMESTAMP('2012-04-30 23:59:59')
    AND c.user_id IS NULL
--
ORDER BY a.monthgroup, b.id #for clarity's sake
给我们期望的结果:


我完全被这句话弄糊涂了:>按他们没有上传简历的日期分组,所以,嗯,你需要按他们没有提交简历的日期分组?你想按天还是按月分组?不同的查询还是在同一个查询中?@SomnathMuluk-我需要按天、周和月进行分组。@Jason'Bug'Fenter-是的,这听起来很愚蠢,但我需要将它们放在一个图表上,它的x轴使用日期。因此,我需要计算在给定时间间隔内没有上传任何简历的用户。为什么用户id
1
不在示例预期结果集中(在
用户id
下)?它没有介于两个日期组之间的简历,所以我不应该这样做吗