简体   繁体   English

如何使用子查询加入自联接?

[英]How to join self join with subquery?

Data:数据:

create table `values` (
     id integer unsigned primary key auto_increment,
     value double,
     `time` time
);

insert into `values` (time, value) values
  ('00:00:01', 1),
  ('00:00:02', 2),
  ('00:00:03', 3),
  ('00:01:01', 4),
  ('00:01:02', 5),
  ('00:01:03', 6);

and fiddle of same http://sqlfiddle.com/#!9/ec3e8/1和小提琴相同的http://sqlfiddle.com/#!9/ec3e8/1

SELECT
    vs1.time as t1,
    vs1.value as v1,
    vs2.time as t2,
    vs2.value as v2
FROM `values` vs1, `values` vs2
JOIN (
    SELECT MIN(time) as mint, MAX(time) as maxt FROM `values`
    GROUP BY hour(time), minute(time)
) as te on vs1.time = te.mint AND vs2.time = te.maxt
WHERE vs1.id != vs2.id AND hour(vs1.time) = hour(vs2.time) AND minute(vs1.time) = minute(vs2.time)

I have a timeseries data in mysql.我在 mysql 中有一个时间序列数据。 I want to aggreate some statistics from it with one sql query.我想用一个 sql 查询从中聚合一些统计信息。 I'd like group values by time, and then get minimum, maximum, first and last value from group.我想按时间对值进行分组,然后从组中获取最小值、最大值、第一个和最后一个值。

I know that mysql doesn't have aggregate functions, ctes, first and last functions, otherwise this would be trivial.我知道 mysql 没有聚合函数、ctes、first 和 last 函数,否则这将是微不足道的。

So my plan is to create a product of all rows (join table with itself) and then join it with min and max times of each interval to get first and last value from interval, but this gives error.所以我的计划是创建所有行的乘积(将表与自身连接),然后将它与每个间隔的最小和最大时间连接起来,以从间隔中获取第一个和最后一个值,但这会产生错误。

Unknown column 'vs1.time' in 'on clause'

What's wrong with my query?我的查询有什么问题? And can use the same product of rows to also get minimum and maximum or do I need to join another query with group by ?并且可以使用相同的行乘积来获得最小值和最大值,还是我需要使用group by加入另一个查询?

Another option would be to make a procedure or so it in some programming language.另一种选择是用某种编程语言制作一个过程。 Procedure is not an option.程序不是一种选择。 I'd like to compare performance of raw SQL and doing this in programming language.我想比较原始 SQL 的性能并在编程语言中执行此操作。

This should work on mysql 5.6.这应该适用于 mysql 5.6。

You are mixing the pre-1992 comma-separated join syntax with proper ANSI joins, which you shouldn't.您将 1992 年之前的逗号分隔连接语法与正确的 ANSI 连接混合在一起,您不应该这样做。 The docs ( https://dev.mysql.com/doc/refman/5.7/en/join.html ) state clearly:文档( https://dev.mysql.com/doc/refman/5.7/en/join.html )清楚地说明:

However, the precedence of the comma operator is less than that of INNER JOIN, CROSS JOIN, LEFT JOIN, and so on.但是,逗号运算符的优先级低于 INNER JOIN、CROSS JOIN、LEFT JOIN 等。 If you mix comma joins with the other join types when there is a join condition, an error of the form Unknown column 'col_name' in 'on clause' may occur.如果在存在连接条件时将逗号连接与其他连接类型混合使用,则可能会出现“on 子句”中的“未知列”“col_name”形式的错误。

Replacing the comma with CROSS JOIN makes it work: FROM `values` vs1 CROSS JOIN `values` vs2 .CROSS JOIN替换逗号使其工作: FROM `values` vs1 CROSS JOIN `values` vs2

However, I find most of your conditions superfluous.但是,我发现您的大多数条件都是多余的。 Plus changing the order of joins for readability (especially in order not to pretend to be cross-joining):加上更改连接顺序以提高可读性(特别是为了不假装交叉连接):

SELECT
    vs1.time as t1,
    vs1.value as v1,
    vs2.time as t2,
    vs2.value as v2
FROM 
(
  SELECT MIN(time) as mint, MAX(time) as maxt 
  FROM `values`
  GROUP BY hour(time), minute(time)
) as te
JOIN `values` vs1 ON vs1.time = te.mint
JOIN `values` vs2 ON vs2.time = te.maxt
ORDER BY vs1.time;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM