我有一个名为records
的MySQL表。以下是其内容。
id record_id Data1 Data2 Time
1 1 null 1 1/1/16
2 1 1 null 1/3/16
3 1 2 null 1/4/16
4 1 null 3 1/5/16
5 2 1 null 2/1/16
6 2 1 null 2/3/16
7 2 7 null 2/4/16
8 2 null 5 2/5/16
我想有一个MySQL查询来检索每个record_id
的每列的最后一条非空记录。结果看起来像;
record_id Data1 Data2 Time
1 2 3 1/5/16
2 7 5 2/5/16
这个问题的棘手部分是涉及多个列。
答案 0 :(得分:4)
SELECT t1.*
FROM yourTable t1
INNER JOIN
(
SELECT record_id, MAX(Time) AS Time
FROM yourTable
GROUP BY record_id
) t2
ON t1.record_id = t2.record_id AND
t1.Time = t2.Time
如果您只想获得数据和时间列的最大值,请查看@Matt给出的答案。但是你的语言让人不清楚你真正想要的是什么。
<强>更新强>
这样的事情可能会给你想要的结果:
SELECT a.record_id,
a.Data1,
b.Data2,
c.Time
FROM
(
SELECT t1.record_id,
t1.Data1
FROM yourTable t1
INNER JOIN
(
SELECT record_id,
MAX(CASE WHEN Data1 IS NULL THEN 0 ELSE id END) AS Data1Id
FROM yourTable
GROUP BY record_id
) t2
ON t1.record_id = t2.record_id AND
t1.Id = t2.Data1Id
) a
INNER JOIN
(
SELECT t1.record_id,
t1.Data2
FROM yourTable t1
INNER JOIN
(
SELECT record_id,
MAX(CASE WHEN Data2 IS NULL THEN 0 ELSE id END) AS Data2Id
FROM yourTable
GROUP BY record_id
) t2
ON t1.record_id = t2.record_id AND
t1.Id = t2.Data2Id
) b
ON a.record_id = b.record_id
INNER JOIN
(
SELECT t1.record_id,
t1.Time
FROM yourTable t1
INNER JOIN
(
SELECT record_id,
MAX(CASE WHEN Data2 IS NULL THEN 0 ELSE id END) AS TimeId
FROM yourTable
GROUP BY record_id
) t2
ON t1.record_id = t2.record_id AND
t1.Id = t2.TimeId
) c
ON a.record_id = c.record_id
答案 1 :(得分:4)
这个可以解决你的问题:
select
record_id,
substring_index(group_concat(Data1 order by Time desc), ',', 1) Data1,
substring_index(group_concat(Data2 order by Time desc), ',', 1) Data2,
substring_index(group_concat(Time order by Time desc), ',', 1) Time
from records
group by record_id
;
它可能没有其他答案那么快,但是是另一个版本......试一试。如果表格中有Data3
列,则可以复制/粘贴Data1
列,只需将此列的所有引用更改为新列。
只是为了解释这是如何工作的:group_concat
函数将列的所有非空值与分隔符(默认为,
)连接起来。您可以在连接之前订购列。它有点像Oracle,Postgre和其他人的窗口函数...... substring_index
只是得到第一个连接值,因为列表是按时间降序排列的。
答案 2 :(得分:1)
看起来你只想要最大的data1,max data2和max time,这将是简单的聚合:
SELECT
record_id
,MAX(Data1) as Data1
,MAX(Data2) as Data2
,MAX(Time) as Time
FROM
yourTable
GROUP BY
record_id
SQL小提琴http://www.sqlfiddle.com/#!9/d95bc1/2
如果需要每列最新的非空值,您可以使用:
SELECT t.record_id, MAX(t.Data1) as Data1, MAX(t.Data2) as Data2, MAX(t.Time) as Time
FROM
yourTable t
LEFT JOIN
(
SELECT
record_id, MAX(Time) as MaxTime
FROM
yourTable t
WHERE
Data1 IS NOT NULL
GROUP BY
record_id
) d1
ON t.record_id = d1.record_id
AND t.Time = d1.MaxTime
LEFT JOIN
(
SELECT
record_id, MAX(Time) as MaxTime
FROM
yourTable t
WHERE
Data2 IS NOT NULL
GROUP BY
record_id
) d2
ON t.record_id = d2.record_id
AND t.Time = d2.MaxTime
WHERE
d1.record_id IS NOT NULL
OR d2.record_id IS NOT NULL
GROUP BY
t.record_id
使用Tim的方法,您实际上仍然可以查看结果,查看最新的Data1记录,然后查看最新的Data2记录然后汇总,这样它们不仅仅是所有内容的MAX,而是代表Data1的最新2条记录1 1表示Data2。
这部分的SQL小提琴:http://www.sqlfiddle.com/#!9/d95bc1/10
答案 3 :(得分:1)
我希望有一个MySQL查询来检索每个
record_id
的每列的最后一条非空记录。
当然,还有一点不清楚的是你如何确定一行是 last 行,因为根据定义,数据库中的行是无序的。
因此,我的解释是,您希望每个不同Data1
的最后非空Data2
,Time
和record_id
列值值。如果行值比另一行值高id
,则行值被视为 last 。
假设我的理解是正确的,以下查询将起作用:
select t.record_id,
(select t2.Data1
from tbl t2
where t2.record_id = t.record_id
and t2.Data1 is not null
order by t2.id desc
limit 1) as Data1,
(select t2.Data2
from tbl t2
where t2.record_id = t.record_id
and t2.Data2 is not null
order by t2.id desc
limit 1) as Data2,
(select t2.Time
from tbl t2
where t2.record_id = t.record_id
and t2.Time is not null
order by t2.id desc
limit 1) as Time
from tbl t
group by t.record_id
order by t.record_id