SQL从具有内连接和限制的两个表中选择[重复]

Posted

技术标签:

【中文标题】SQL从具有内连接和限制的两个表中选择[重复]【英文标题】:SQL Selecting from two Tables with inner join and limit [duplicate] 【发布时间】:2021-08-16 21:15:01 【问题描述】:

我有两张桌子ServiceStatus。服务表只包含一个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从具有内连接和限制的两个表中选择[重复]

SQL中有几种连接?有啥区别?(左连右连内连和外连?)

基于另一列的最大值的列上的 SQL 内连接 [重复]

SQL - 从一个表中选择,同时在另外两个表之间进行内部连接(多对多表和另一个表)

从 Docker 容器内连接到 SQL Server Express 会导致评估密码时出错

从具有相同值的两个表中选择数据后结果重复