powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Сложная выборка, не подпадающая под какой-либо join
10 сообщений из 10, страница 1 из 1
Сложная выборка, не подпадающая под какой-либо join
    #39960671
Glad_r
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Доброго времени всем.
Имеем продукт, структуру поменять нельзя. Данные поменять нельзя . Есть права только на выполнение select . При больших бы правах выкрутился, но тут что-то не могу решить задачку.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
CREATE TABLE defects ( // дефекты
  id int(11) NOT NULL auto_increment, // внутренний идентификатор
  defect_id varchar(250) NOT NULL, // идентификатор дефекта
  test_change_id int(11) NOT NULL, // идентификатор теста, в котором выявлен дефект (равен tests.last_status_change_id, либо test_changes.id )
  case_id int(11) NULL, // идентификатор оргининального теста (равен tests.case_id)
  project_id int(11) NOT NULL, // идентификатор проекта (равен projects.id)
  PRIMARY KEY (id),
  KEY ix_defects_defect_id (defect_id),
  KEY ix_defects_test_change_id (test_change_id),
  KEY ix_defects_case_id (case_id)
);

INSERT INTO defects VALUES
(1001,'Defect-1',63713,78096,11),
(1005,'Defect-2',68969,81542,11),
(1006,'Defect-3',68969,81542,11),
(1007,'Defect-3',69005,81542,11),
(1007,'Defect-2',69005,81542,11);

CREATE TABLE tests ( // тесты
  id int(11) NOT NULL auto_increment, // внутренний идентификатор
  run_id int(11) NOT NULL, // идентификатор прогона (равен runs.id)
  case_id int(11) NULL, // идентификатор оргининального теста
  last_status_change_id int(11) default NULL, // идентификатор последнего изменения
  tested_by int(11) default NULL, // идентификатор пользователя (равен users.id)
  PRIMARY KEY  (id),
  KEY ix_tests_run_id (run_id)
  );

INSERT INTO tests VALUES
(10000001,1,78096,63713,101),
(20000002,2,81542,69005,102),


CREATE TABLE test_changes ( //история изменения статусов теста
  id int(11) NOT NULL auto_increment, // внутренний идентификатор
  test_id int(11) NOT NULL, // идентификатор теста (равен tests.id)
  user_id int(11) NOT NULL, // идентификатор пользователя (равен users.id)
  defects varchar(250) default NULL, // идентификатор дефекта (равен defects.id)
  project_id int(11) NOT NULL, // идентификатор проекта (равен projects.id)
  run_id int(11) NOT NULL, // идентификатор прогона (равен runs.id)
  PRIMARY KEY  (id),
  KEY ix_test_changes_test_id (test_id)
  );

INSERT INTO test_changes VALUES
(63713,668033,101,'Defect-1',11,1)
(68969,716147,102,'Defect-2, Defect-3',11,2)
(69005,716147,102,'Defect-2, Defect-3',11,2);


CREATE TABLE projects ( //проекы
  id int(11) NOT NULL auto_increment, // внутренний идентификатор
  `name` varchar(250) NOT NULL, // наименование проекта
  PRIMARY KEY  (id)
);

INSERT INTO users VALUES
(11, 'Основной проект'),
(12, 'Тестовый проект');

CREATE TABLE runs ( //прогоны
  id int(11) NOT NULL auto_increment, // внутренний идентификатор
  project_id int(11) NOT NULL, // идентификатор проекта (равен projects.id)
  `name` varchar(250) NOT NULL, // наименование прогона
  passed_count int(11) NOT NULL default '0', // счётчик тестов данного типа
  retest_count int(11) NOT NULL default '0', // счётчик тестов  данного типа
  failed_count int(11) NOT NULL default '0', // счётчик тестов  данного типа
  untested_count int(11) NOT NULL default '0', // счётчик тестов данного типа
  blocked_count int(11) NOT NULL default '0', // счётчик тестов данного типа
  PRIMARY KEY  (id),
  KEY ix_runs_project_id (project_id)
);

INSERT INTO runs VALUES
(1,11,'Первая проверка в основном проекте',100,0,1,0,0),
(2,11,'Вторая проверка в основном проекте',98,1,2,0,0),
(3,12,'Первая проверка в тестовом проекте',50,3,1,5,1);

CREATE TABLE users ( //пользователи
  id int(11) NOT NULL auto_increment, // внутренний идентификатор
  `name` varchar(250) NOT NULL, // наименование пользователя
  PRIMARY KEY  (id)
);

INSERT INTO users VALUES
(101, 'Вася'),
(102, 'Петя'),
(103, 'Маша');



Сервер mysql-server 5.5.55-0+deb8u1.

На выходе надо получить следующий вид
projects.name AS project_name, runs.name AS run_name, runs.passed_count, runs.failed_count, runs.untested_count, runs.blocked_count, user.name AS user_name, количество дефектов

Если до projects.name AS project_name, runs.name AS run_name, runs.passed_count, runs.failed_count, runs.untested_count, runs.blocked_count всё легко и вяжется обычным join по is, то с дефектами возникла проблема.
Подскажите, как посчитать, сколько ошибок завл пользователь в каждом прогоне.

Заранее низкий поклон.
...
Рейтинг: 0 / 0
Сложная выборка, не подпадающая под какой-либо join
    #39960697
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Glad_r
На выходе надо получить следующий вид
А таблицей вместе с данными, которые должны получиться на показанных исходных данных - не?
...
Рейтинг: 0 / 0
Сложная выборка, не подпадающая под какой-либо join
    #39960708
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Блин, трудно было проверить скрипты на работоспособность? ляп на ляпе...

Вот fiddle . Добавьте связи, и запрос, который получает все данные без обработок и группировок, одной плоской таблицей. Убедитесь, что работает. Выложите обновлённую ссылку.
...
Рейтинг: 0 / 0
Сложная выборка, не подпадающая под какой-либо join
    #39960710
Gluck99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akina
Блин, трудно было проверить скрипты на работоспособность? ляп на ляпе...
Я даже исправлять не стал. Кому нужен результат - мне или автору?
...
Рейтинг: 0 / 0
Сложная выборка, не подпадающая под какой-либо join
    #39960722
Glad_r
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akina, Gluck99 спасибо за отклик и критику.
Честно не знал про такие возможности, что можно сразу вставлять и отлаживать данные. Сохранил в заметках.

Akina, как просили, добавил вывод результата, в том виде, что я ожидаю.
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=e0fda063af7959f5fc2d03d5d1957400
...
Рейтинг: 0 / 0
Сложная выборка, не подпадающая под какой-либо join
    #39960762
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Glad_r , я же специально просил:
Akina
Добавьте связи, и запрос, который получает все данные без обработок и группировок, одной плоской таблицей.

Воссоздавать связи по комментариям - дохлое дело.
...
Рейтинг: 0 / 0
Сложная выборка, не подпадающая под какой-либо join
    #39960773
Glad_r
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akina,
в самой базе таблицы не как не связаны, в чистом виде (relation) нет связи.
Могу чисто со своих комментариев вынести связи
...
Рейтинг: 0 / 0
Сложная выборка, не подпадающая под какой-либо join
    #39960875
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хрен с ими, связями. Дайте запрос, который связывает ВСЕ таблицы в одну большую, и при этом ничего не теряет.
Просто связи-то, похоже, избыточные - и при этом потенциально противоречивые...
...
Рейтинг: 0 / 0
Сложная выборка, не подпадающая под какой-либо join
    #39961584
Glad_r
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akina,

Первая часть
Код: sql
1.
2.
3.
 SELECT p.name AS project_name, r.name AS run_name, r.passed_count, r.failed_count, r.untested_count, r.blocked_count, r.id
  FROM projects p
 INNER JOIN runs r ON p.id = r.project_id


К ней остётся добавить сумму дефектов, но там как раз проблема из-за множественных связей. Если бы defects через left join был связан с tests, тогда tests.tested_by=user.id, tests.run_id=runs.id.
Но остаются те дефекты, которые не свяжутся. И тут как раз нужна помощь
...
Рейтинг: 0 / 0
Сложная выборка, не подпадающая под какой-либо join
    #39961853
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вы странный. Только Вы обладаете сведениями о том, где что с чем связано. Где связь, а где просто переопределённые данные.

Пока из всего этого вылезает, похоже, такая логика:

Есть проекты. Таблица projects.
В каждом проекте есть несколько прогонов (тестов). Таблица runs, связанная с projects.

Пока всё гладко. А вот дальше...

Чисто в теории - дальше должны идти отдельные тесты. Таблица tests. Тут всё понятно, кроме странного поля case_id (идентификатор оригинального теста), которое на что-то ссылается, но на что? Ладно, хрен с им, идём чисто по равенству значений, а там куда-то вылезем. Вяжем тесты к прогонам. JOIN tests t ON t.run_id = r.id

Дальше. Если брести по значениям, то видно, что к таблице тестов привязывается таблица дефектов. Логика уже спряталась далеко и надёжно, поэтому тупо бредём за значениями. JOIN defects d ON t.case_id = d.case_id

Ну и осталась таблица изменения статусов test_changes, которая, опять же судя по значениями, связана с таблицей дефектов через поле test_change_id. Пишем, вообще не думая. JOIN test_changes c ON c.id = d.test_change_id

Поскольку тесты, их изменения, и дефекты, если судить по данным, могут отсутствовать в отдельных прогонах, последние три связи делаем левыми, и по совокупности имеем

Код: sql
1.
2.
3.
4.
5.
FROM projects p
JOIN runs r ON p.id = r.project_id
LEFT JOIN tests t ON t.run_id = r.id
LEFT JOIN defects d ON t.case_id = d.case_id
LEFT JOIN test_changes c ON c.id = d.test_change_id



Ну и добавляем юзеров.

Поскольку юзер присутствует как в tests, так и в test_changes, придётся связывать две копии таблицы юзеров. Добавляем и получаем

Код: sql
1.
2.
3.
4.
5.
6.
7.
FROM projects p
JOIN runs r ON p.id = r.project_id
LEFT JOIN tests t ON t.run_id = r.id
LEFT JOIN defects d ON t.case_id = d.case_id
LEFT JOIN test_changes c ON c.id = d.test_change_id
LEFT JOIN users u1 ON u1.id = t.tested_by
LEFT JOIN users u2 ON u2.id = c.user_id



Если всё это запустить с SELECT * , то получится 6 записей. fiddle .

Нам же нужны только три, то есть размножившиеся записи придётся "схлопывать" группировкой. Для того, чтобы сделать это правильно (вернее, чтобы после группировки, которая достаточно очевидна, правильно получить агрегированные поля) надо понять:

1) Какой из двух user_name нужен.
2) Как именно получено значение defect_count.
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Сложная выборка, не подпадающая под какой-либо join
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]