嵌套查询和加入

时间:2017-02-15 15:13:18

标签: mysql join subquery

作为SQL的初学者,我可以做简单的任务,但我现在正在努力解决多个嵌套查询问题。 我的问题是我有3个这样的表:

Case表:

id   nd    date                  username
--------------------------------------------
1    596   2016-02-09 16:50:03   UserA
2    967   2015-10-09 21:12:23   UserB
3    967   2015-10-09 22:35:40   UserA
4    967   2015-10-09 23:50:31   UserB
5    580   2017-02-09 10:19:43   UserA

Value表:

case_id   labelValue_id    Value          Type
-------------------------------------------------
1         3633             2731858342     X
1         124              ["864","862"]  X
1         8981             -2.103         X
1         27               443            X
...       ...              ...            ...
2         7890             232478         X
2         765              0.2334         X
...       ...              ...            ...

Label表:

id     label
----------------------
3633   Value of W             
124    Value of X   
8981   Value of Y     
27     Value of Z

显然,我想加入这些表格。所以我可以这样做:

SELECT *
from Case, Value, Label
where Case.id= Value.case_id
and Label.id = Value.labelValue_id

但我得到了所有的东西,而我希望更具体。

我想要的是对Case表进行一些过滤,然后使用结果id加入另外两个表。我想:

  1. 过滤Case.nd,以便如果有相同nd的多个实例,请选择最旧的实例,
  2. 限制查询中的nd数。例如,我希望能够加入表格只有2,3,4等......不同的nd。
  3. 使用此查询在ValueLabel表格上建立联接。
  4. 例如,查询1和2的输出将是:

    id   nd    date                  username
    --------------------------------------------
    1    596   2016-02-09 16:50:03   UserA
    2    967   2015-10-09 21:12:23   UserB
    

    如果我要求2个不同的nd。 nd 967出现了几次,但我们采用最老的一次。

    事实上,我认为我发现了如何做所有这些事情,但我不知道如何合并它们。

    要选择最早的nd,我可以这样做:

    select min((date)), nd,id 
        from Case
        group by nd
    

    然后,为了限制输出中的nd数,我发现了这一点(基于thisthat):

    select *,
    @num := if(@type <> t.nd, @num + 1, 1) as row_number,
    @type := t.nd as dummy
        from(
            select min((date)), nd,id 
            from Case
            group by nd
            ) as t
            group by t.nd
            having row_number <= 2 -- number of output
    

    它有效,但我觉得它变慢了。

    最后,当我尝试使用此子查询和其他两个表进行连接时,处理将继续进行。

    在我的研究期间,我可以找到问题的每个部分的答案,但我无法合并它们。另外,对于“计数”问题,我想限制nd的数量,我觉得它有点远。

    我意识到这是一个很长的问题,但我想我错过了一些内容,我想尽可能多地提供详细信息。

2 个答案:

答案 0 :(得分:0)

过滤案例表以消除所有最老的nds,

select * from [case] c
where date = (Select min(date) from case
              where nd = c.nd)

然后将其加入其他表:

select * from [case] c
   join value v on v.Case_id = c.Id
   join label l on l.Id = v.labelValue_id
where date = (Select min(date) from [case]
              where nd = c.nd)

将它限制为一定数量的记录,有一个特定于mysql的命令,我认为它叫Limit

select * from [case] c
   join value v on v.Case_id = c.Id
   join label l on l.Id = v.labelValue_id
where date = (Select min(date) from [case]
              where nd = c.nd)
Limit 4 -- <=== will limit return result set to 4 rows

如果你只想要nd的前N个值的记录,那么Limit会继续限制要检索的nd值的子查询:

select * from [case] c
   join value v on v.Case_id = c.Id
   join label l on l.Id = v.labelValue_id
where date = (Select min(date) from [case]
              where nd = c.nd)
   and nd In (select distinct nd from [case]
              order by nd desc Limit N) 

答案 1 :(得分:0)

最后,这对我来说效果很好:

select *
from (
        select *
        from Case
        join (
            select nd as T_ND, date as T_date
            from Case
            where nd in (select distinct nd from Case)
            group by T_ND Limit 5 -- <========= Limit of nd's
        ) as t
        on Case.nd = t.T_ND
        where date = (select min(date) 
                                from Case
                                where nd = t.T_ND)
    ) as subquery

    join Value 
        on Value.context_id = subquery.id
    join Label
        on Label.id = Value.labelValue_id

感谢@charlesbretana带领我走上正确的道路:)。