从第二个表中选择正确行的问题

时间:2012-03-29 19:11:07

标签: mysql select join match

我希望得到你们中的一些人的帮助。

我的问题是这样的: 表1包含一些网络交换机端口配置信息。我每天都会将所有更改填入此表中以获取历史记录。 该表将包含大约12000行。该表每天将增长约10-20行。 该表有这样的行(tbl_port_config): id,switch_id,port_id,port_name,change_date

第二个表(tbl_port_errors)包含所有端口的错误统计信息。此表将每四个小时更新一次,并且仅插入有错误的端口。 该表如下所示: id,date,switch_id,port_id,error_counter1,error_counter2,....

到目前为止很容易; - )

我现在正在寻找一个select语句,它给出了特定时间范围内的所有开关和端口。我的问题是我想在查询中添加来自tbl_port_config的port_name,以使输出更加用户友好。

假设我想在2012.03.29查找交换机1端口1上的错误,我想从表tbl_port_config获取端口名称,并在一段时间内获取该端口的错误计数器。

但在我的表tbl_port_name中,该交换机端口的最新条目通常具有比查询日期更早的日期。

此外,可能会发生最新值不正确的情况。 让我们假设我们有一个特定的交换机和端口跟随端口名称的历史记录 2012.03.01 name1 2012.03.02 name2 2012.03.08 name8 2012.03.29 name29

现在我想获得该端口的日期2012.03.07的错误计数器。日期的正确名称是name2,它应包含在输出中。 我有什么想法可以解决这个问题吗?

此致 安德烈亚斯


-- phpMyAdmin SQL Dump
-- version 3.4.10.1

-- http://www.phpmyadmin.net

-- Host: localhost
-- Generation Time: Mar 30, 2012 at 11:04 AM
-- Server version: 5.5.19
-- PHP Version: 5.3.8
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";

SET time_zone = "+00:00";

-- Database: test

-- Table structure for table tbl_port_config

CREATE TABLE IF NOT EXISTS tbl_port_config (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
switch_id int(10) unsigned NOT NULL,
port_id int(10) unsigned NOT NULL COMMENT 'decimal port id',
port_name varchar(32) NOT NULL,
changedate date NOT NULL COMMENT 'Date when port config has been changed',
PRIMARY KEY (id)

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;

-- Dumping data for table tbl_port_config

INSERT INTO tbl_port_config (id, switch_id, port_id, port_name, changedate) VALUES
(1, 2, 0, '---', '2012-01-01'),
(2, 2, 0, 'name1', '2012-01-15'),

(3, 2, 0, 'name2', '2012-01-19');

-- Table structure for table tbl_port_errors

CREATE TABLE IF NOT EXISTS tbl_port_errors (
id int(11) NOT NULL AUTO_INCREMENT,
date datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
switch_id int(11) NOT NULL,
port_id int(11) NOT NULL,
err_discards_c3 int(11) NOT NULL,
err_rx_enc_in int(11) NOT NULL,
err_rx_enc_out int(11) NOT NULL,
PRIMARY KEY (id),
KEY date (date),
KEY switch_id (switch_id),
KEY port_id (port_id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Tabelle mit allen error countern' AUTO_INCREMENT=8 ;

--

-- Dumping data for table tbl_port_errors

test) VALUES
(1, '2012-01-13 20:00:00', 2, 0, 150, 151, 152),
(2, '2012-01-13 20:00:00', 2, 1, 151, 151, 151),
(3, '2012-01-13 20:00:00', 2, 2, 152, 152, 152),
(4, '2012-01-13 22:00:00', 2, 0, 220, 220, 220),
(5, '2012-01-13 22:00:00', 2, 2, 222, 222, 222),
(6, '2012-01-20 18:00:00', 2, 0, 180, 180, 180),
(7, '2012-01-22 14:00:00', 2, 0, 140, 140, 140);

我运行的选择语句如下:
SELECT p.date, p.switch_id, p.port_id, p.err_discards_c3, c.port_name, c.changedate FROM tbl_port_errors p left join  tbl_port_config c on p.switch_id = c.switch_id and p.port_id = c.port_id WHERE p.err_discards_c3 > 0 

并将返回这样的行:
  

date switch_id port_id err_discards_c3 port_name changedate 2012-01-13 20:00:00 2 0 150 --- 2012-01-01 2012-01-13 20:00:00 2 0 150 name1 2012-01-15 2012-01-13 20:00:00 2 0 150 name2 2012-01-19 2012-01-13 22:00:00 2 0 220 --- 2012-01-01 2012-01-13 22:00:00 2 0 220 name1 2012-01-15 2012-01-13 22:00:00 2 0 220 name2 2012-01-19 2012-01-20 18:00:00 2 0 180 --- 2012-01-01 2012-01-20 18:00:00 2 0 180 name1 2012-01-15 2012-01-20 18:00:00 2 0 180 name2 2012-01-19 2012-01-22 14:00:00 2 0 140 --- 2012-01-01 2012-01-22 14:00:00 2 0 140 name1 2012-01-15 2012-01-22 14:00:00 2 0 140 name2 2012-01-19

只有斜体中的行对于Switch_ID 2和Port_ID 0是正确的。

我想只为表格tbl_port_errors中的每一行输入一行具有正确端口名称的行。
请仔细查看已更改日期的不同日期。
我正在寻找与所选端口错误日期相比的下一个最早的日期 我希望你能理解我的问题。 很抱歉格式不佳,但我还要了解这个论坛的工作原理......

此致 安德烈亚斯

2 个答案:

答案 0 :(得分:0)

SELECT tbl_port_config。*,(SELECT TOP 1 error_counter1 FROM tbl_port_errors WHERE switch_id = tbl_port_config.switch_id)as error_counter_1 WHERE ......

答案 1 :(得分:0)

MySQL使用LIMIT而不是top。如果您不想要最新但最新的,请将其限制为一行并将其偏移一行。

SELECT 
    tbl_port_config.*, 
    (SELECT 
        error_counter1 
    FROM 
        tbl_port_errors 
    WHERE 
        switch_id = tbl_port_config.switch_id
    ORDER BY id desc
    LIMIT 1,1) as error_counter_1