SQL从具有内连接和限制的两个表中选择[重复]
Posted
技术标签:
【中文标题】SQL从具有内连接和限制的两个表中选择[重复]【英文标题】:SQL Selecting from two Tables with inner join and limit [duplicate] 【发布时间】:2021-08-16 21:15:01 【问题描述】:我有两张桌子Service
和Status
。服务表只包含一个name
和一个id
| id | name |
|----|-------|
| 1 | Test1 |
| 2 | Test2 |
还有一个像这样的状态表
| id | status | service_id | timestamp |
|----|--------|------------|---------------------------|
| 1 | OK | 1 | October, 15 2015 09:03:07 |
| 2 | OK | 1 | October, 15 2015 09:08:07 |
| 3 | OK | 2 | October, 15 2015 10:05:23 |
| 4 | OK | 2 | October, 15 2015 10:15:23 |
我想得到这样的数据
| id | name | status | timestamp |
|----|-------|--------|---------------------------|
| 1 | Test1 | OK | October, 15 2015 09:08:07 |
| 2 | Test2 | OK | October, 15 2015 10:15:23 |
服务数据的最新状态。这个说法我试过了
SELECT ser.id, ser.name, a.status, a.timestamp
from Service ser
inner join (select * from status
order by Status.timestamp
DESC limit 1) as a
on a.service_id = ser.id
但我只得到
| id | name | status | timestamp |
|----|-------|--------|---------------------------|
| 2 | Test2 | OK | October, 15 2015 10:15:23 |
如何更改语句以获得我想要的?
用于测试SQL Fiddle
【问题讨论】:
基于 SQLFiddle 中使用的 DBMS 添加了mysql
标签
您想要每个服务的最新状态?
@jarlh 是的,这就是我想要的
【参考方案1】:
你可以这样做:
SELECT
ser.id,
ser.name,
s.status,
s.timestamp
FROM Service ser
INNER JOIN status as s ON s.service_id = ser.id
INNER JOIN
(
SELECT
service_id,
MAX(timestamp) AS MaxDate
FROM status
GROUP BY service_id
) AS a ON a.service_id = s.service_id
AND a.MaxDate = s.timestamp;
与子查询的连接:
SELECT
service_id,
MAX(timestamp) AS MaxDate
FROM status
GROUP BY service_id
将消除除日期最近的状态之外的所有状态。
【讨论】:
谢谢你,这很好:)【参考方案2】:对于每一个服务,只有在没有后一个服务存在时才使用NOT EXISTS
返回状态:
select ser.id, ser.name, st.status, st.timestamp
from service ser
left join status st1 on ser.id = st1.service_id
where not exists (select 1 from status st2
where st2.service_id = st1.service_id
and st2.timestamp > st1.timestamp)
可选地执行LEFT JOIN
也可以返回没有任何状态的服务。如果不需要,请切换到 JOIN
。
【讨论】:
【参考方案3】:试试这个...
SELECT ser.id, ser.name, a.status, a.max_timesatmp_rm
from Service ser
inner join (select *,row_number() over (partiton by service_id order by timestamp desc ) as max_timesatmp_rm from status
) as a
on a.service_id = ser.id
where a.max_timesatmp_rm=1;
【讨论】:
【参考方案4】:你可以在没有像这样的子查询的情况下得到这个结果
SELECT s.id, s.name,
SUBSTRING_INDEX(GROUP_CONCAT(st.status ORDER BY st.timestamp DESC),',',1) AS status_value,
SUBSTRING_INDEX(GROUP_CONCAT(st.timestamp ORDER BY st.timestamp DESC),',',1) AS time_stamp
FROM Service s
JOIN Status st ON(st.service_id = s.id)
GROUP BY s.id
ORDER BY s.id
输出是
id name status_value time_stamp
1 Test1 OK 2015-10-15 09:08:07
2 Test2 OK 2015-10-15 10:15:23
【讨论】:
【参考方案5】:您可以使用此查询获得结果
SELECT MAX(s.id),
sr.id,
sr.name,
s.status,
s.timestamp
FROM Service AS sr
INNER JOIN status AS s ON s.service_id = sr.id
GROUP BY sr.id
ORDER BY s.id ASC
我认为它对你有用
【讨论】:
以上是关于SQL从具有内连接和限制的两个表中选择[重复]的主要内容,如果未能解决你的问题,请参考以下文章
SQL - 从一个表中选择,同时在另外两个表之间进行内部连接(多对多表和另一个表)