用于组合在不同列中具有重叠日期的行的SQL查询

时间:2013-05-15 15:10:40

标签: sql join timestamp postgresql-8.4

这是一个奇怪的问题。让我布置我的桌子结构......

我的'服务器'表格给出了我服务器的状态信息(我每分钟都会得到一些这样的消息)。我的'客户'表更新了客户端信息(显然是连接到服务器的客户端)。

群集中的一个服务器始终是“主要”,可以这么说(其他服务器是次要的)。每个客户端都会向我的每台服务器提供延迟信息。

我需要查看客户端延迟大于60秒的行,但我也需要知道每个服务器的状态。

这里是示例表(服务器,然后是客户端):

  server_name |   server_role   |      sstat_time
--------------+-----------------+----------------------
  server1     |  PRIMARY        |  2013-05-15 01:01:00
  server2     |  SECONDARY      |  2013-05-15 01:02:00
  server3     |  SECONDARY      |  2013-05-15 01:02:00
  server1     |  PRIMARY        |  2013-05-15 01:05:00
  server2     |  SECONDARY      |  2013-05-15 01:06:00
  server3     |  PRIMARY        |  2013-05-15 01:10:00
  server1     |  SECONDARY      |  2013-05-15 01:11:00
  server1     |  PRIMARY        |  2013-05-15 01:22:00
  server3     |  SECONDARY      |  2013-05-15 01:23:00

客户端:

  client_name |  server_dest  |  latency  |     cstat_time
  ------------+---------------+-----------+--------------------
    client1   |  server1      |  2        | 2013-05-15 01:01:30
    client2   |  server2      |  68       | 2013-05-15 01:01:40
    client2   |  server1      |  99       | 2013-05-15 01:01:50
    client1   |  server3      |  5        | 2013-05-15 01:10:00
    client2   |  server3      |  78       | 2013-05-15 01:10:30
    client2   |  server1      |  15       | 2013-05-15 01:10:50

所以,我想要的查询结果是:

client_name   |  server_name  |  latency  |  server_role |    cstat_time
--------------+---------------+-----------+--------------+--------------------
    client2   |  server2      |  68       |  SECONDARY   | 2013-05-15 01:01:04
    client2   |  server1      |  99       |  PRIMARY     | 2013-05-15 01:01:50
    client2   |  server3      |  78       |  PRIMARY     | 2013-05-15 01:10:30

我需要知道延迟超过60秒的时间,以及潜在服务器在该时间点的角色。

任何线索如何做到这一点?

我在Postgres 8.4上运行。

4 个答案:

答案 0 :(得分:2)

如果我理解正确,您正在尝试确定特定时间的服务器角色。了解提供了“开始时间”,但“结束时间”位于该服务器的下一行。要解决此问题,您需要在同一行创建一个包含开始和结束时间的临时表,以解决JOIN BETWEEN操作。所以它在MS SQL中看起来像这样(对不起,你可能需要为Postgres翻译)

-- This is TSQL code SQL Server 2008 compatible
create table #svr(
    server_name varchar(10),
    server_role varchar(10),
    stime datetime
)
create table #client(
    client_name varchar(10),
    server_name varchar(10),
    latency int,
    ctime datetime
)
create table #role(
    server_name varchar(10),
    server_role varchar(10),
    stime datetime,
    etime datetime
)
insert #svr values
    ('server1','PRIMARY','2013-05-15 01:01:00'),
    ('server2','SECONDARY','2013-05-15 01:02:00'),
    ('server3','SECONDARY','2013-05-15 01:02:00'),
    ('server1','PRIMARY','2013-05-15 01:05:00'),
    ('server2','SECONDARY','2013-05-15 01:06:00'),
    ('server3','PRIMARY','2013-05-15 01:10:00'),
    ('server1','SECONDARY','2013-05-15 01:11:00'),
    ('server1','PRIMARY','2013-05-15 01:22:00'),
    ('server3','SECONDARY','2013-05-15 01:23:00')

insert #client values
('client1','server1',2,'2013-05-15 01:01:30'),
('client2','server2',68,'2013-05-15 01:01:40'),
('client2','server1',99,'2013-05-15 01:01:50'),
('client1','server3',5,'2013-05-15 01:10:00'),
('client2','server3',78,'2013-05-15 01:10:30'),
('client2','server1',15,'2013-05-15 01:10:50')

insert #role
select s1.server_name, s1.server_role, s1.stime, s2.stime
from (  select row_number() over(order by server_name,stime) as RowId,*
        from #svr
     )  as s1
join (  select row_number() over(order by server_name,stime) as RowId,*
        from #svr
     )  as s2
on s1.RowId = s2.RowId-1

select C.client_name, C.server_name, C.latency, R.server_role, C.ctime
from #client C
left join #role R on R.server_name = C.server_name 
and C.ctime between R.stime and R.etime
WHERE C.latency > 60

结果如下:

Result in SSMS

答案 1 :(得分:1)

这里是解决方案

SELECT C.Client_name , S.Server_name, C.latency , S.Server_role, C.Cstat_time  
from Server_table S
INNER JOIN Client C
ON C.server_dest = S.server_name
Where C.latency > 60 

答案 2 :(得分:1)

正如模型所示,我看到你无法通过简单地将两个表(客户端和服务器)交叉到服务器名称来获取'server_role'的数据。

澄清这一点,查询

select c. *, s.server_role 
from client c left outer join server s    
on c.server_dest = s.server_name
where c.latency> 60

我们返回了以下信息:

client_name   |  server_name  |  latency  |  server_role |    cstat_time
--------------+---------------+-----------+--------------+--------------------
    client2   |  server2      |  68       |  SECONDARY   | 2013-05-15 01:01:40
    client2   |  server2      |  68       |  SECONDARY   | 2013-05-15 01:01:40
    client2   |  server1      |  99       |  PRIMARY     | 2013-05-15 01:01:50
    client2   |  server1      |  99       |  PRIMARY     | 2013-05-15 01:01:50
    client2   |  server1      |  99       |  SECONDARY   | 2013-05-15 01:01:50
    client2   |  server1      |  99       |  PRIMARY     | 2013-05-15 01:01:50
    client2   |  server3      |  78       |  SECONDARY   | 2013-05-15 01:10:30
    client2   |  server3      |  78       |  PRIMARY     | 2013-05-15 01:10:30
    client2   |  server3      |  78       |  SECONDARY   | 2013-05-15 01:10:30

我会要求分析确实​​在99的延迟时间内获得PRIMARY服务器角色,以便将client2送到服务器'server2'。

如果在两个表中使用时间,必须知道服务器角色的规则。

答案 3 :(得分:0)

如果我理解正确的话,这是一个简单的连接查询:

select c.*, sys.server_role
from client c left outer join
     server s
     on c.server_desc = s.server_name
where c.latency > 60