Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/72.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
Mysql 将一个表与另一个表的最新行联接_Mysql_Sql_Join - Fatal编程技术网

Mysql 将一个表与另一个表的最新行联接

Mysql 将一个表与另一个表的最新行联接,mysql,sql,join,Mysql,Sql,Join,我有两个MySQL表,包含以下信息: 表1(基本信息) 表2(时间序列数据) 我需要进行联接,以便将表1中的所有条目与表2中最近的条目联接起来。因此,输出将如下所示: 输出 name | url | status | date a | www.a.com | ok | 22/12/14 b | www.b.com | ok | 22/12/14 c | www.c.com | ok | 22/12/14 什么查询会给出上面的输出?我通常在S

我有两个MySQL表,包含以下信息:

表1(基本信息)

表2(时间序列数据)

我需要进行联接,以便将表1中的所有条目与表2中最近的条目联接起来。因此,输出将如下所示:

输出

name | url       | status | date
a    | www.a.com | ok     | 22/12/14
b    | www.b.com | ok     | 22/12/14
c    | www.c.com | ok     | 22/12/14

什么查询会给出上面的输出?

我通常在SQLServer中工作,因此如果适用,您必须更正语法,但基本上您要按可用的最大日期分组,并且只返回那些行。请参阅下面的代码并尝试一下!让我知道这是否有帮助

SELECT t1.name, t1.url, t2.status, max(t2.date)
FROM table1 t1
INNER JOIN table2 t2 ON t1.name = t2.name
GROUP BY t1.name, t1.url, t2.status, max(t2.date)

试试这个,按日期分组

SELECT  a.*,b.*
FROM    table1 a
        INNER JOIN
        (
            SELECT  table2.name name2, MAX(Date) max_date, status
            FROM    table2
            GROUP   BY name, status

        ) b ON  a.name = b.name2

这是个棘手的问题。您可以做的是连接第二个表两次,一次是查找“最新”的行,第二次是获取实际数据

SELECT t1.name, t1.url, t2.status, t2.date
FROM table1 t1
LEFT JOIN (SELECT name, max(date) as mx from table2 GROUP BY name) as X ON X.name = t1.name
LEFT JOIN table2 t2 0N t2.name = X.name AND t2.date = X.mx
我用这个名字加入。您通常会使用一些键(ID)


这样做的目的是将表2连接到自身,以便查找给定名称的最新日期。

不带分组或聚合的查询:

SELECT t1.name, t1.url, t21.status, t21.date
FROM table1 t1
INNER JOIN table2 t21 ON t1.name = t21.name
LEFT JOIN table2 t22 ON t21.name = t22.name AND t21.date < t22.date
WHERE t22.name IS NULL;
MySQL不支持(目前还不支持?)流行的窗口功能,这些功能被添加到目前大多数其他RDBMS(Oracle、SQL Server、PostgreSQL)中。这就是使用行号编写此类查询的自然方式:

SELECT name, url, status, date from (
 SELECT t1.name, t1.url, t2.status, t2.date,
 ROW_NUMBER() OVER (PARTITION BY t1.name ORDER BY t2.date DESC) rn
 FROM table1 t1 INNER JOIN table2 t2 ON t1.name = t2.name
) tmp WHERE rn = 1;

我专门从事这种对时间敏感的设计,以下是我的工作。您的第二个表是一个
版本化的
表,与源代码管理系统一样,当数据发生更改时,旧数据会保留,只会创建一个带有更改日期的新副本。一个小的改变可以添加完整的双时态功能,但这不是你的问题,是吗?(八)

如果像我发现的那样是真的,你会发现绝大多数对这个表的查询都是针对当前数据的,那么有一件事你可能要考虑的是创建一个视图来只显示每一行的当前版本。

create view tab2 as
select *
from   table2 t2
where  date =(
    select  max( date )
    from    table2
    where   name = t2.name );
然后,您可以简单地将第一个表与视图连接起来,以便与表1中的数据进行一对一的关联,而只与表2中的当前数据进行关联。这允许您抽象出数据的时间敏感性

如果有理由不能使用视图(比如一个老学校的DBA一想到加入视图就发作),那么您必须将整个过程编写为一个查询。幸运的是,这并不困难,但抽象很方便

select t1.Name, t1.URL, t2.Status, t2.Date
from   table1 t1
join   table2 t2
  on   t2.Name = t1.Name
  and  t2.Date =(
       select  max( Date )
       from    table2
       where   name = t2.name );
某些DBMS不允许在联接中使用子查询。在这种情况下,只需将其移动到WHERE子句:

select t1.Name, t1.URL, t2.Status, t2.Date
from   table1 t1
join   table2 t2
  on   t2.Name = t1.Name
where  t2.Date =(
       select  max( Date )
       from    table2
       where   name = t2.name );

如果Name和Date形成了一个唯一的索引(或者是显式定义的,或者是因为它们构成了表的主键),那么您会发现性能比您最初想象的要好得多。尝试一下,并与其他方法进行比较。

看起来很有希望,但我收到了一个“无效使用组函数”错误。很抱歉,这可能是语法问题。看来你的答案已经够多了,请试试他们的答案。我很想知道哪一个适合您。聚合不能出现在ON子句中,除非它出现在HAVING子句或select列表中包含的子查询中?使用视图的另一个好处可能是,您可以编写“before”或“instead of”触发器将Update语句转换为新版本表的正确插入,从而维护抽象。
SELECT t1.name, t1.url, t2.status, t2.date
FROM table1 t1 INNER JOIN table2 t2 ON t1.name = t2.name
WHERE t2.date = (SELECT max(date) FROM table2 t22 WHERE t22.name = t2.name);
SELECT name, url, status, date from (
 SELECT t1.name, t1.url, t2.status, t2.date,
 ROW_NUMBER() OVER (PARTITION BY t1.name ORDER BY t2.date DESC) rn
 FROM table1 t1 INNER JOIN table2 t2 ON t1.name = t2.name
) tmp WHERE rn = 1;
create view tab2 as
select *
from   table2 t2
where  date =(
    select  max( date )
    from    table2
    where   name = t2.name );
select t1.Name, t1.URL, t2.Status, t2.Date
from   table1 t1
join   table2 t2
  on   t2.Name = t1.Name
  and  t2.Date =(
       select  max( Date )
       from    table2
       where   name = t2.name );
select t1.Name, t1.URL, t2.Status, t2.Date
from   table1 t1
join   table2 t2
  on   t2.Name = t1.Name
where  t2.Date =(
       select  max( Date )
       from    table2
       where   name = t2.name );