Проблемы с выбором правильной строки из второй таблицы - PullRequest
0 голосов
/ 29 марта 2012

Я надеюсь получить помощь от одного из вас.

Моя проблема такова: Таблица 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,….

Пока все просто; -)

Сейчас я ищу оператор выбора, который дает мне все коммутаторы и порты определенного временного диапазона. Моя проблема в том, что я хочу добавить имя_порта из tbl_port_config в свой запрос, чтобы сделать вывод более удобным для пользователя.

Допустим, я хочу найти ошибки на порту 1 коммутатора 1 в 2012.03.29 и хочу получить имя порта из таблицы tbl_port_config и счетчик ошибок этого порта за период времени.

Но в моей таблице tbl_port_name самая последняя запись этого порта коммутатора очень часто имеет дату, которая старше даты запроса.

Кроме того, может случиться так, что не самое текущее значение будет правильным. Предположим, что мы имеем для конкретного коммутатора и порта следующую историю имени порта 2012.03.01 имя1 2012.03.02 имя2 2012.03.08 имя8 2012.03.29 имя29

Теперь я хочу получить счетчик ошибок даты 2012.03.07 для этого порта. Правильное имя для даты - name2, которое должно быть включено в выход. Любые идеи, как я могу решить это?

С уважением, Andreas

<code>
-- phpMyAdmin SQL Dump<br>
-- version 3.4.10.1  </p>

<h2>-- <a href="http://www.phpmyadmin.net" rel="nofollow">http://www.phpmyadmin.net</a></h2>

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

<h2>SET time_zone = "+00:00";</h2>

<h2>-- Database: <code>test</code></h2>

<h2>-- Table structure for table <code>tbl_port_config</code></h2>

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

<h2>) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;</h2>

<h2>-- Dumping data for table <code>tbl_port_config</code></h2>

<p>INSERT INTO <code>tbl_port_config</code> (<code>id</code>, <code>switch_id</code>, <code>port_id</code>, <code>port_name</code>, <code>changedate</code>) VALUES<br>
(1, 2, 0, '---', '2012-01-01'),<br>
(2, 2, 0, 'name1', '2012-01-15'),  </p>

<h2>(3, 2, 0, 'name2', '2012-01-19');</h2>

<h2>-- Table structure for table <code>tbl_port_errors</code></h2>

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

<p>--  </p>

<h2>-- Dumping data for table <code>tbl_port_errors</code></h2>

<p>INSERT INTO <code>tbl_port_errors</code> (<code>id</code>, <code>date</code>, <code>switch_id</code>, <code>port_id</code>, <code>err_discards_c3</code>, <code>err_rx_enc_in</code>, err_rx_enc_out</code>) VALUES<br>
(1, '2012-01-13 20:00:00', 2, 0, 150, 151, 152),<br>
(2, '2012-01-13 20:00:00', 2, 1, 151, 151, 151),<br>
(3, '2012-01-13 20:00:00', 2, 2, 152, 152, 152),<br>
(4, '2012-01-13 22:00:00', 2, 0, 220, 220, 220),<br>
(5, '2012-01-13 22:00:00', 2, 2, 222, 222, 222),<br>
(6, '2012-01-20 18:00:00', 2, 0, 180, 180, 180),<br>
(7, '2012-01-22 14:00:00', 2, 0, 140, 140, 140);  </p>

<p>
Моя инструкция выбора, которую я запускаю, выглядит следующим образом:
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 

И вернет строки так:
  </p>

<p>date    switch_id   port_id err_discards_c3 port_name   changedate
<strong><em>2012-01-13 20:00:00  2   0   150 --- 2012-01-01</em></strong>
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
<strong><em>2012-01-13 22:00:00  2   0   220 --- 2012-01-01</em></strong>
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
<strong><em>2012-01-20 18:00:00  2   0   180 name2   2012-01-19</em></strong>
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
<strong><em>2012-01-22 14:00:00  2   0   140 name2   2012-01-19</em></strong>

Только строка в курсив верна для Switch_ID 2 и Port_ID 0.

Я хочу получить только одну строку с правильным именем порта для каждой строки, которая находится в таблице tbl_port_errors.
Пожалуйста, присмотритесь к различным датам изменения и даты .
Я ищу следующую самую старую дату по сравнению с датой ошибки выбранного порта.
Я надеюсь, что вы можете понять мою проблему. Извините за плохое форматирование, но я должен немного узнать, как работает этот форум ...

С уважением, Andreas

Ответы [ 2 ]

0 голосов
/ 30 марта 2012

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 
0 голосов
/ 30 марта 2012

SELECT tbl_port_config. *, (SELECT TOP 1 error_counter1 ОТ tbl_port_errors WHERE switch_id = tbl_port_config.switch_id) как error_counter_1 WHERE ......

...