У меня есть две таблицы:подсчета MySQL изменения значения колонные в наборе результатов
1) задачи - представляет задачу. Он имеет только первичный ключ, так как все связанные данные находятся в таблице task_version (задача HAS_MANY task_version).
CREATE TABLE task(
id int(11) unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
);
и выборка данных:
INSERT INTO task VALUES ('1');
INSERT INTO task VALUES ('2');
2) task_version - Любое изменение в любой задаче создает новую строку в этой таблице. task_id должен быть внешним ключом (пропущен для простоты). Это должно быть полное ведение всех изменений в задаче.
CREATE TABLE `task_version` (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
task_id int(11) DEFAULT NULL,
name varchar(255) DEFAULT NULL,
text varchar(255) DEFAULT NULL,
status int(11) DEFAULT NULL,
PRIMARY KEY (id)
);
Образец данных:
INSERT INTO `task_version` VALUES ('1', '1', 'Name of task', 'Text of task', '1');
INSERT INTO `task_version` VALUES ('2', '1', 'Name of task', 'Text of task', '1');
INSERT INTO `task_version` VALUES ('3', '1', 'Name of task', 'Text of task', '2');
INSERT INTO `task_version` VALUES ('4', '1', 'Name of task', 'Text of task', '1');
INSERT INTO `task_version` VALUES ('5', '2', 'Name', 'Text', '1');
Что мне нужно, чтобы получить статус изменяется количество на задачу.
Очевидно я не могу просто запросить различные статусы, как это:
SELECT
(
SELECT
COUNT(DISTINCT status)
FROM task_version
WHERE task_id = t.id
) AS distinct_statuses_per_task,
t.id AS task_id
FROM task t
INNER JOIN task_version tv ON t.id = tv.task_id
GROUP BY t.id
Поскольку distinct_statuses_per_task всего различные значения не изменяется qunatity. Если кто-то меняет статус от 1 до 2, от 2 до 1 и от 1 до 2 раз, мы получим эти Статусы последовательности:
1
2
1
2
Таким образом, мы имеем 2 различных состояния (1, 2), но 3 изменений состояния (1> 2, 2> 1, 1> 2), поэтому он не работает.
Я разработал решение с переменными пользователя MySQL. Это подзапрос, что я хочу, чтобы встроить в основной запрос:
SELECT
CASE WHEN (status != @prev_status AND @prev_status IS NOT NULL)
THEN @status_changes_quantity := @status_changes_quantity + 1
END as incrementing_logic,
@status_changes_quantity AS status_changes_quantity,
@prev_status := status AS save_prev
FROM task_version,
(
SELECT
@prev_status := NULL,
@status_changes_quantity := 0
) as task_version_with_additional_vars
WHERE task_id = 1 --Hardcoded task_id
ORDER BY status_changes_quantity DESC
LIMIT 1
Это работает как автономный запрос с закодированным TASK_ID. Но мне нужно встроить этот запрос в подзапрос, чтобы получить количество изменений статусов для каждой задачи.
Я не могу заставить его работать. Проблема в том, что когда я устанавливаю переменные в части запроса SELECT, они становятся частью результата запроса. Подзапрос должен возвращать одиночный скаляр, но мой запрос возвращает таблицу (incrementing_logic, status_changes_quantity, save_prev) Я не знаю sintax, как избавиться от этих нежелательных colomns (incrementing_logic, save_prev).
I судимого это:
SELECT
(
SELECT
CASE WHEN (status != @prev_status AND @prev_status IS NOT NULL)
THEN @status_changes_quantity := @status_changes_quantity + 1
END as incrementing_logic,
@status_changes_quantity AS status_changes_quantity,
@prev_status := status AS save_prev
FROM task_version,
(
SELECT
@prev_status := NULL,
@status_changes_quantity := 0
) as task_version_with_additional_vars
WHERE task_id = t.id
ORDER BY status_changes_quantity DESC
LIMIT 1
) AS status_changes_quantity,
t.id AS task_id,
tv.status AS task_status
FROM task t
INNER JOIN task_version tv ON t.id = tv.task_id
Очевидно получили:
[Err] 1241 - Operand should contain 1 column(s)
А потом я пытался обернуть подзапросы таблицу в другую TMP, чтобы избавиться от переменных полей и значения гер скалярного:
SELECT
(
SELECT
status_changes_quantity
FROM
(
SELECT
CASE WHEN (status != @prev_status AND @prev_status IS NOT NULL)
THEN @status_changes_quantity := @status_changes_quantity + 1
END as incrementing_logic,
@status_changes_quantity AS status_changes_quantity,
@prev_status := status AS save_prev
FROM task_version,
(
SELECT
@prev_status := NULL,
@status_changes_quantity := 0
) as task_version_with_additional_vars
WHERE task_id = t.id
ORDER BY status_changes_quantity DESC
LIMIT 1
) AS tmp_table
) AS status_changes_quantity,
t.id AS task_id,
tv.status AS task_status
FROM task t
INNER JOIN task_version tv ON t.id = tv.task_id
Я также получил аранжировку, которая теперь невидима в области подзапроса:
[Err] 1054 - Unknown column 't.id' in 'where clause'
Возможно, кто-то знает, как решить мою проблему. Чтобы исправить мой запрос или предложить совершенно другой алгоритм.
Заранее спасибо.