Mysql SQL内部查询

Mysql SQL内部查询,mysql,sql,database,Mysql,Sql,Database,我有一个用户表。每个用户都有特定的类型,但是用户的类型可以更改,我需要记录每个学生过去的类型 所以我有 user_table ---------------- user_id user_first_name ... type_table --------------- type_id type_desc type_change_table ---------------- change_id user_id type_id date_of_cha

我有一个用户表。每个用户都有特定的类型,但是用户的类型可以更改,我需要记录每个学生过去的类型

所以我有

user_table
----------------
user_id     user_first_name ...


type_table
---------------
type_id   type_desc     


type_change_table
----------------
change_id    user_id   type_id      date_of_change   date_of_input
希望上面的三个表是可以理解的。因此,如果我想更改用户类型,我将类型更改输入类型更改表,在输入日期上加盖时间戳,这可能与用户更改其类型的实际日期不同-更改日期。然后,我有一个完整的日志,记录每个用户的类型历史,以及每次更改输入数据库的时间

我的问题是试图执行某个SQL查询。 英文查询为:

获取所有使用date_of_input TODAY更改其类型且更改前类型为type的用户

其中TYPE和TODAY是变量。 e、 g.我想知道今天谁输入了类型更改,以及更改是从什么类型进行的

我真的不知道如何在SQL中处理这种查询,我认为这至少需要一个内部查询,以按ASC顺序选择倒数第二个用户类型

我应该如何进行此查询?

使用此

SELECT * FROM user_table WHERE user_id IN(
    SELECT  user_id 
    FROM type_change_table tct INNER JOIN
        type_table tt ON tct.type_ID = tt.type_id
    WHERE 
        date_of_change = 'PUT DATE HERE' AND 
        type_desc = 'PUT TYPE HERE'
)
我假设type\u change\u表通知新的type\u id,而不是旧的。如果是这样,您需要在日期输入找到的所需更改日期之前获取最大更改日期。我选择了一系列字段来获取有关更改的最大信息,但您可以选择真正需要的内容

选择的结果将是:

SELECT 
   A.change_id, 
   A.date_of_change, 
   A.date_of_input ,
   A.USER_ID, 
   D.user_first_name, 
   B.type_id id_old_type, 
   E.type_desc id_old_type_desc, 
   A.type_id id_new_Type, 
   F.type_desc id_new_type_desc
FROM (
    -- This subquery gets the last change type --> maximum date before actual change
    SELECT actual_type.type_id, actual_type.user_id, actual_type.change_id, actual_type.date_of_change, actual_type.date_of_input, max(old_type.date_of_change) last_change_before_today
    FROM type_change_table actual_type 
    INNER JOIN type_change_table old_type
      ON actual_type.user_id = old_type.user_id
    WHERE DATE_FORMAT(actual_type.date_of_input, '%Y-%m-%d') = '2014-07-18'
       AND old_type.date_of_change < actual_type.date_of_change
    GROUP BY actual_type.user_id, actual_type.change_id
) A
-- B gets the last user type
INNER JOIN type_change_table B
   ON A.user_id = B.user_id
   AND A.last_change_before_today = B.date_of_change
-- D gets the user data 
INNER JOIN user_table D
   ON A.user_id = D.user_id
-- E gets the description of old_type
INNER JOIN type_table E
  ON B.type_id = E.type_id
-- F gets the descrioption of new type
INNER JOIN type_Table F
  ON A.type_id = F.Type_id
WHERE E.type_desc = 'Type 1'
您可以定义参数来替换查询中的值


请查看SQL FIDLE

在exists子查询中使用ORDER by和LIMIT 1查找倒数第二条记录。我想你是指倒数第二次使用描述顺序

不确定您希望使用哪一个日期字段,我选择了date_of_change,根据需要更改

   /*Get all the users who changed their type with date_of_input TODAY 
    and whose type before the change was TYPE.*/


SET @today := '2014-07-26 00:00:00';
SET @type  := 4;

SELECT
      tct.user_id
    , ut.user_first_name
    , tct.type_id
    , tt.type_desc
FROM type_change_table tct
      INNER JOIN user_table ut
                  ON tct.user_id = ut.user_id
      INNER JOIN type_table tt
                  ON tct.type_id = tt.type_id
WHERE tct.date_of_change = @today
      AND EXISTS (
            SELECT
                  NULL
            FROM type_change_table prev
            WHERE tct.user_id = prev.user_id
                  AND date_of_change < @today
                  AND prev.type_id = @type
        ORDER BY date_of_change DESC
        LIMIT 1
      );

请参见

您能否为一些样本数据播种,提供预期输出?它必须是ASC订单中倒数第二种类型的用户?更改日期是在输入日期之后,还是在输入日期之前?还是没关系?如果你愿意,考虑一下这个简单的两步过程:1。如果您还没有这样做,请提供适当的DDL和/或SQLFIDLE,以便我们可以更轻松地复制问题。2.如果您还没有这样做,请提供与步骤1中提供的信息相对应的所需结果集。不是我提供的,但您的查询不符合要求。您刚刚在一个简单的where子句中添加了2个条件。请重新阅读问题。一个条件是日期=今天,另一个条件是特定类型,并且变化小于今天