Mysql - необходимо получить последнюю из таблицы A при ссылке на таблицу B

0

Я создаю инструмент для отслеживания ошибок для ударов. У меня проблемы с небольшой проблемой, связанной с контролем версий моих данных.

У меня есть таблица "action", где я храню все данные о действии (desription, кто ввел его, статус и т.д.). У меня также есть таблица action_status, где каждый раз, когда статус изменен (от не выполненного, выполняется, завершается и т.д.), Он регистрируется здесь. То, что я не могу сделать, это перечислить действия с их последним значением статуса. Вы заметите, что таблица состояния имеет две строки, одна из них была отправлена, а otehr нет. Я ТОЛЬКО хочу видеть строку, которая отправила = 0 (последняя дата, которую я бы предположил..)

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

Вот мои таблицы и некоторые примеры данных: Я обезьяна?

CREATE TABLE IF NOT EXISTS `action` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `id_action` int(11) NOT NULL,
  `id_priority` int(11) NOT NULL,
  `revision` int(11) NOT NULL DEFAULT '1',
  `reference` varchar(255) NOT NULL,
  `department` int(11) NOT NULL,
  `id_parent` int(11) NOT NULL DEFAULT '0',
  `sort_order` int(11) NOT NULL,
  `description` text NOT NULL,
  `date_start` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `date_end` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `date_created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY (`id`),
  KEY `id` (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=6 ;

--
-- Dumping data for table `action`
--

INSERT INTO `action` (`id`, `id_action`, `id_priority`, `revision`, `reference`, `department`, `id_parent`, `sort_order`, `description`, `date_start`, `date_end`, `date_created`) VALUES
(1, 1, 1, 1, '1', 1, 0, 2, 'Test Action revision test 1 a', '0000-00-00 00:00:00', '0000-00-00 00:00:00', '2011-06-17 00:00:00'),
(2, 1, 1, 2, '0', 1, 0, 2, 'Test Action revision test 1 b', '0000-00-00 00:00:00', '0000-00-00 00:00:00', '2011-06-17 00:00:00'),
(3, 2, 1, 1, '0', 1, 0, 1, 'Test Action revision test 2 a', '0000-00-00 00:00:00', '0000-00-00 00:00:00', '2011-06-17 00:00:00'),
(4, 2, 1, 2, '0', 1, 0, 1, 'Test Action revision test 2 b', '0000-00-00 00:00:00', '0000-00-00 00:00:00', '2011-06-17 00:00:00'),
(5, 3, 2, 1, '0', 1, 0, 0, 'Test Action revision test 3 b', '0000-00-00 00:00:00', '0000-00-00 00:00:00', '2011-06-17 00:00:00');

-- --------------------------------------------------------

--
-- Table structure for table `action_status`
--

CREATE TABLE IF NOT EXISTS `action_status` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `id_department` int(11) NOT NULL,
  `id_priority` int(11) NOT NULL,
  `id_action` int(11) NOT NULL,
  `status` int(11) NOT NULL,
  `submitted` tinyint(4) NOT NULL,
  `approved` tinyint(4) NOT NULL,
  `published` tinyint(4) NOT NULL,
  `date_now` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY (`id`),
  KEY `id` (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;

--
-- Dumping data for table `action_status`
--

INSERT INTO `action_status` (`id`, `id_department`, `id_priority`, `id_action`, `status`, `submitted`, `approved`, `published`, `date_now`) VALUES
(1, 1, 1, 2, 3, 1, 1, 1, '2011-06-20 16:36:09'),
(2, 1, 1, 2, 5, 0, 0, 0, '2011-06-20 16:40:09');


CREATE TABLE IF NOT EXISTS `priority` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `description` text NOT NULL,
  PRIMARY KEY (`id`),
  KEY `id` (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;

--
-- Dumping data for table `priority`
--

INSERT INTO `priority` (`id`, `description`) VALUES
(1, 'Test Priority'),
(2, '2nd Priority');

И мой "проблема" SQL

SELECT `action`.`id_priority`, `priority`.`description` as priority, `action`.`reference`, `action`.`description` as action, `action`.`id_action`, `action`.`date_start`, `action`.`date_end`, `action`.`id_parent`, `action_status`.`status`, `action`.`revision`, `action_status`.`submitted`, `action_status`.`date_now`

FROM (`action`)

LEFT JOIN action_status ON
  `action_status`.`id_action` = `action`.`id_action`

JOIN `priority` ON
  `action`.`id_priority` = `priority`.`id`

WHERE
action.department = 1 AND
action.revision =(SELECT MAX(ar.revision) FROM action as ar WHERE action.id_action = ar.id_action)

GROUP BY `action`.`id_action`

ORDER BY `id_priority` asc, `id_parent` asc, `sort_order` asc
  • 0
    Вы хотите увидеть все записи из "Action", которые никогда не имели записи в таблице "Action_Status" ??? (т. е. требует левого соединения). Кроме того, ваш комментарий о том, что вы видите только те, у которых отправлено = 0 (что должно быть последней записью, в противном случае выполняется несколько одновременных задач) Что делать, если последняя запись для данного действия завершена (передана, кроме 0). Вы тоже хотите это включить?
Теги:
sorting
join
greatest-n-per-group

2 ответа

0
Лучший ответ

Если я понял это хорошо и вам нужны только действия с максимальной ревизией, попробуйте что-то вроде этого:

SELECT *

FROM

    (SELECT `action`.`id_action`, max(`action`.`revision`), 
        (select id 
         from action as a 
         where a.id_action = action.id_action 
         order by revision desc 
         limit 1) as id_with_max_revision

    FROM `action`

    WHERE
    action.department = 1

    GROUP BY `action`.`id_action`

    ) as action_max_revision
JOIN action on action_max_revision.id_with_max_revision = action.id
LEFT JOIN action_status ON
      `action_status`.`id_action` = `action`.`id_action`

JOIN `priority` ON
      `action`.`id_priority` = `priority`.`id`
ORDER BY `id_priority` asc, `id_parent` asc, `sort_order` asc

Внутренний запрос выбирает действия с максимальной ревизией, а внешний запрос выполняет другую грань, которая не является ядром проблемы: -)

1

одна хорошая рекомендация - если вы попросите о помощи, упростите свой пример, насколько это возможно, чтобы показать основной корень вашей проблемы. Никто не попытается понять ваш сложный код таким образом... What I can't seem to do is list the actions with their latest status value. Вы говорите о последнем значении статуса, поэтому я ожидаю, что вы хотите получить последнюю запись из таблицы action_status, но в своем запросе вы проверяете максимальную ревизию в таблице действий... И почему вы группируете action_id, когда вы хотите, чтобы compaI должен признать, что я вообще не понимаю дизайн.

Во всяком случае, я думаю, что несколько лет назад я решал аналогичную проблему, см. эту функцию для функции MySQL (http://bugs.mysql.com/bug.php?id=2020) и мой ответ на ' 7 июля 13:12 '. См. Следующий пример: он должен помочь вам:

Предположим, у вас есть таблица с ценой за каждый товар в каждом магазине. Для каждого товара вы хотите увидеть минимальную цену и соответствующий магазин, в котором вы получите его за цену! Точно так же, как в вашем примере - вам нужна запись с максимальной ревизией.

create table prices ( goods varchar(10), price double, store varchar(10) );

insert into prices values ('car', 200, 'Amazon'), ('car', 150, 'CarStore'), ('Bread', 2, 'Baker1'), ('Bread', 1, 'Baker2');

select goods, min(price), (select store from prices as p where p.goods = prices.goods
order by price limit 1) as store
from prices
group by goods;

Надеюсь, это поможет. Если вы хотите выбрать больше столбцов, просто выберите идентификатор вместо хранилища и сделайте его как подзапрос и снова присоединитесь к таблице через идентификатор.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню