【问题标题】:SQL Selecting from two Tables with inner join and limit [duplicate]SQL从具有内部连接和限制的两个表中选择[重复]
【发布时间】:2022-11-24 16:46:11
【问题描述】:

我有两个表 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 是的,这就是我想要的

标签: mysql sql


【解决方案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
        

        我想这对你有用

        【讨论】:

          猜你喜欢
          • 2021-11-04
          相关资源
          最近更新 更多