Столбец ответа на запрос, полученный из комбинации столбцов в другой таблице

TNM Staging Я делаю свой первый проект. У меня есть некоторые данные: t_stage — от t0 до t4, n_stage — от n0 до n3, а m_stage — от m0 и m1. Разные их комбинации дают разные результаты. Таким образом, t1,n2,m0 — это этап 3a, t4,n1,m1 — это этап 4.

Я хочу, чтобы запрос содержал эти конкретные шаблоны уже в синтаксисе, чтобы при запуске запроса появлялся дополнительный столбец, определяющий этап, зависящий от чисел t, n и m, которые находятся в таблице для каждой записи. .

Как и выше, если t равно t1, n равно n2 и m равно 0, для этой записи будет дополнительный столбец с заголовком «Этап» с этапом 3a и так далее для вариантов. (Комбинации см. на изображении).

Я просто не могу понять, как создать этот дополнительный столбец «Этап» и заполнить его ответом при выполнении запроса.

Я, вероятно, упускаю что-то очень очевидное. Как я уже сказал, это мой первый проект с MySQL. Я привык к MSAccess и продолжаю думать, что значительная часть автоматизации все еще будет там.

Я ДОЛЖЕН хранить отдельные оценки T, N и M для каждой записи в схеме для возможного последующего запроса.

Я посмотрел на DERIVED, UNION, WHERE и HAVING и просто не знаю, на правильном ли я пути.

  CREATE TABLE pathology (
  pathology_id VARCHAR(100) NOT NULL PRIMARY KEY,
  medical_data_id VARCHAR(100),
  grade INT 
    CONSTRAINT grade CHECK (grade IN (1, 2, 3, 4)),
  tumour_weight DECIMAL (3,3)                       -- in grams
  tumour_circumference DECIMAL (2,2)                -- in cms
  tumour_stage ENUM('t0','t1', 't2', 't3', 't4'),
  node_stage ENUM('n0', 'n1', 'n2', 'n3'),
  met_stage ENUM('m0', 'm1')
  );

Существует 40 различных комбинаций. У всех 40 есть сцена? Вы наверняка могли бы создать вторую таблицу, содержащую все 40 возможных комбинаций и полученный идентификатор этапа, и выполнить LEFT JOIN, чтобы включить ее в свой запрос.

Tim Roberts 03.09.2024 04:00

@TimRoberts Поскольку вторая таблица содержит все возможные комбинации, нет смысла использовать LEFT JOIN, это должно быть INNER JOIN.

Barmar 03.09.2024 04:58

«Итак, t1,n2,m0 — это Stage3a» — ПОЧЕМУ? как из этой комбинации получается 3а?

P.Salmon 03.09.2024 08:38

@P.Salmon, это способ сортировки стадий рака. Никаких математических рассуждений. Просто накапливаются разные баллы в зависимости от результатов патологии. Таким образом, если m равно 1, это всегда будет стадия 4, потому что 1 означает, что есть метастазы.

Donna Cannon 03.09.2024 09:47

@TimRoberts Мне приходится хранить отдельные оценки t,n,m для каждой записи, сохраненные в схеме, для возможного запроса позже.

Donna Cannon 03.09.2024 09:50

@P.Salmon, эта таблица, которую он использовал Researchgate.net/figure/…

Donna Cannon 03.09.2024 09:56

@DonnaCannon Вам НЕ нужны результаты, хранящиеся в записи. На самом деле это считается плохой практикой, потому что это излишне. Это не Нормальная Форма. Где бы вы ни запросили запись, вы просто используете JOIN. Фактически, MySQL позволяет вам создать CREATE VIEW, который ВЫГЛЯДИТ как таблица, но выполняет JOIN за вас, оставляя структуру базы данных нетронутой.

Tim Roberts 03.09.2024 18:39
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
0
7
71
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

У вас должна быть таблица всех возможных комбинаций, записанная в вашей БД. Затем вы можете соединить таблицу случаев с соответствующими строками в таблице комбинаций, используя поля T, N и M, что должно дать вам искомый результат.

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

SELECT (...), Y.STAGE 
FROM X, Y
WHERE X.T=Y.T AND X.N=Y.N AND X.M=Y.M

Согласно опубликованной вами таблице, в некоторых случаях допускается любое T или любое N. Для таких случаев вам следует создать дополнительные группы ИЛИ. Дайте мне знать, если вам нужна дополнительная информация по этому поводу.

Теперь я добавил код таблицы к своему первоначальному вопросу. Я не уверен, ясно ли я это объяснил изначально, но отдельные данные t, n и m должны быть сохранены для каждой записи для возможного отдельного запроса в следующий раз. Так будет ли работать таблица со всеми комбинациями?

Donna Cannon 03.09.2024 10:52

Да, они бы это сделали. Теперь, имея описание таблицы, считайте T как tumour_stage, N как node_stage и M как met_stage. Ваша таблица «патологий» (X) сохранит эти значения. Вам понадобится дополнительная таблица «стадий» (Y), к которой вы соедините патологию с критериями, которые я объяснил выше.

macl 03.09.2024 11:09

Итак, я выполнил этот запрос после создания и заполнения таблицы комбинаций (tnm_staging), и он дал мне заголовок столбца, но не дал данных. Извините, если я упускаю что-то очень очевидное. Я попробовал другую комбинацию, где в этом примере указан pathology_id. ВЫБРАТЬ (pathology_id) общий_этап ИЗ патологии, tnm_staging ГДЕ pathology.tumour_stage=tnm_staging.t_category И pathology.node_stage=tnm_staging.n_category И pathology.met_stage=tnm_staging.n_category;

Donna Cannon 03.09.2024 12:36

@DonnaCannon при условии, что ваша таблица tnm_staging содержит правильную стадию для каждой комбинации t, n и m в поле common_stage, а в вашей таблице патологии есть хотя бы одна запись с полными данными, это должно работать. Точный SQL-запрос должен быть следующим: SELECT pathology_id, tnm_staging.overall_stage FROM pathology, tnm_staging WHERE pathology.tumour_stage=tnm_staging.t_category AND pathology.node_stage=tnm_staging.n_category AND pathology.met_stage=tnm_staging.n_category; - Можете ли вы предоставить примеры данных из вашей таблицы патологий, просто для проверки?

macl 03.09.2024 13:21

Если у вас есть таблица, подобная этой:

--    S a m p l e    D a t a :
Create Table your_table ( id Int, T_stage Text, N_stage Text, M_stage Text );
Insert Into your_table
  Select  1, 'T0', 'N0', 'M0' Union All 
  Select  2, 'T0', 'N1', 'M0' Union All 
  Select  3, 'T0', 'N2', 'M0' Union All   
  Select  4, 'T0', 'N2', 'M1' Union All 
  Select  5, 'T1', 'N0', 'M0' Union All 
  Select  6, 'T1', 'N1', 'M0' Union All 
  Select  7, 'T1', 'N2', 'M0' Union All 
  Select  8, 'T3', 'N1', 'M0' Union All 
  Select  9, 'T3', 'N1', 'M1' Union All 
  Select 10, 'T3', 'N3', 'M0' Union All 
  Select 11, 'T4', 'N2', 'M0' Union All 
  Select 12, 'T4', 'N3', 'M0'; 

... вы можете создать cte (или таблицу), которая определяет различные комбинации этапов T, N и M, давая им общий этап (как в вашей ссылке выше). Я закомментировал последние 3 строки, потому что они различаются и будут обрабатываться выражением Case в основном коде SQL ниже...

WITH
  stages ( overall_stage, T_category, N_category, M_category ) AS
    ( Select 'Stage 0',   'T0',    'N0',    'M0' Union All 
      Select 'Stage 1',   'T1',    'N0',    'M0' Union All 
      Select 'Stage 2A',  'T0',    'N1',    'M0' Union All 
      Select 'Stage 2A',  'T1',    'N1',    'M0' Union All 
      Select 'Stage 2A',  'T2',    'N0',    'M0' Union All 
      Select 'Stage 2B',  'T2', '   N1',    'M0' Union All 
      Select 'Stage 2B',  'T3',    'N0',    'M0' Union All 
      Select 'Stage 3A',  'T0',    'N2',    'M0' Union All 
      Select 'Stage 3A',  'T1',    'N2',    'M0' Union All 
      Select 'Stage 3A',  'T2',    'N2',    'M0' Union All 
      Select 'Stage 3A',  'T3',    'N1',    'M0' Union All 
      Select 'Stage 3A',  'T3',    'N2',    'M0' 
      -- Union All 
      -- Select 'Stage 3B',  'T4',    'Any N', 'M0' Union All 
      -- Select 'Stage 3C',  'Any T', 'N3',    'M0' Union All 
      -- Select 'Stage 4',   'Any T', 'Any N', 'M1'   
    )

... этот cte, если его оставить присоединенным к your_table, должен дать вам ожидаемый общий_этап для каждой строки, оставляя ваши отдельные этапы нетронутыми...

--    M a i n    S Q L : 
Select      t.id, t.T_stage, t.N_stage, t.M_stage, 
            Case When t.M_stage = 'M1' Then 'Stage 4' 
                 When t.N_stage = 'N3' And t.M_stage = 'M0' Then 'Stage 3C'
                 When t.T_stage = 'T4' And t.M_stage = 'M0' Then 'Stage 3B'
                 When s.overall_stage Is Not Null Then s.overall_stage
            Else 'N/A'
            End as overall_stage
From        your_table t
Left Join   stages s ON( s.T_category = t.T_stage And 
                         s.N_category = t.N_stage And 
                         s.M_category = t.M_stage )
Order By    t.id
/*      R e s u l t :
id  T_stage     N_stage     M_stage     overall_stage
--  ---------   ----------  ----------  -------------
 1  T0          N0          M0          Stage 0
 2  T0          N1          M0          Stage 2A
 3  T0          N2          M0          Stage 3A
 4  T0          N2          M1          Stage 4
 5  T1          N0          M0          Stage 1
 6  T1          N1          M0          Stage 2A
 7  T1          N2          M0          Stage 3A
 8  T3          N1          M0          Stage 3A
 9  T3          N1          M1          Stage 4
10  T3          N3          M0          Stage 3C
11  T4          N2          M0          Stage 3B  
12  T4          N3          M0          Stage 3C       */

См. скрипку здесь.

ПРИМЕЧАНИЕ: Выражение Case является последовательным, то есть первым. Когда условие удовлетворено, оно возвращает значение «Тогда» и выходит из Case. Единственная проблема может заключаться в том, какой общий_этап должен быть выбран, если у вас есть комбинация T4-N3-M0, это этап 3C или 3B - я поставил 3C, если это противоположно, просто поменяйте местами эти две строки в выражении Case....

P.S. Лучшим решением было бы создать постоянную таблицу со всеми явными комбинациями трех этапов с соответствующим значением common_stage для каждого. Тогда вам вообще не понадобится выражение Case — просто соединение, выбирающее общий_этап из этой новой таблицы для каждой объединенной строки в вашей_таблице.

Я создал отдельную таблицу под названием tnm_staging. он содержит все комбинации из эталонного изображения, которое я использовал. Я создал внешний ключ для подключения таблицы патологии (которая содержит отдельные оценки t,n,m) к tnm_staging (таблице сочетаний). Я использовал запрос, указанный пользователем выше, но мне не удалось заполнить возвращаемый столбец. Возможно, я использовал неправильный тип соединения.

Donna Cannon 03.09.2024 12:41

Справочное изображение @DonnaCannon не содержит всех явных комбинаций из трех. Есть такие вещи, как ЛЮБОЙ T или Tis, которых нет в данных (T0, T1, T2, T3, T4). Попробуйте сначала адаптировать приведенный выше код к вашему контексту (имя таблицы (your_table) и имена столбцов, начинающиеся с t. в основном SQL выше). В зависимости от чувствительности к регистру вашей базы данных и фактических данных - она ​​может работать как есть. Если ваша база данных чувствительна к регистру и у вас есть «t0» вместо «T0», тогда обработайте это тоже, используя функцию Upper() или Lower() в предложении ON соединения и в условиях Case WHEN...

d r 03.09.2024 12:51

Я создал каждую перестановку, кроме Тиса. Это настолько незначительно, что теоретически не могло бы произойти в тех целях, для которых эта база данных будет использоваться. Я убедился, что случаи одинаковы. Я бы прикрепил код, но в это поле для комментариев он не влезает. Возможно, загружу удаленно и пришлю ссылку. Если у вас есть ссылка на скрипку, возможно, я мог бы сделать это таким образом?

Donna Cannon 03.09.2024 13:05

@DonnaCannon Посмотрите скрипку на dbfiddle.uk/PCC6tT_e Я сгенерировал все комбинации, используя рекурсивные cte (всего 40 комбинаций). Ниже этих комбинаций приведены примеры данных и рабочий основной код sql, извлекающий common_stages.... (Используется Oracle из-за множественных рекурсий и из-за того, что я привык к Oracle)

d r 03.09.2024 13:35
Ответ принят как подходящий

ВТОРОЙ ОТВЕТ (после множества комментариев):

Сначала создайте таблицу tnm_staging со всеми 40 возможными явными комбинациями трех значений столбца, определяющими столбец common_stage для каждого:

--  Combination generator for T 0-4   /    N 0-3    /    M 0-1
CREATE TABLE tnm_staging
WITH
  t_stages ( T_cat ) AS
    ( Select 't0' Union All
      Select 't1' Union All
      Select 't2' Union All
      Select 't3' Union All
      Select 't4'
    ), 
  n_stages (  N_cat ) AS
    ( Select 'n0' Union All
      Select 'n1' Union All
      Select 'n2' Union All
      Select 'n3' 
    ), 
  m_stages ( M_cat )  AS
    ( Select 'm0' Union All
      Select 'm1' 
    ),
  stages as
    ( Select Row_Number() Over(Order By tn.T_cat, tn.N_cat, m.M_cat) as id, 
             'Stage x' as overall_stage, tn.T_cat, tn.N_cat, m.M_cat
      From   ( Select  t.T_cat, n.N_cat 
               From    t_stages t
               CROSS JOIN n_stages n
             ) tn
      CROSS JOIN m_stages m
   ), 
  stage_names ( overall_stage, T_category, N_category, M_category ) AS
    ( Select 'Stage 0',   't0',    'n0',    'm0' Union All 
      Select 'Stage 1',   't1',    'n0',    'm0' Union All 
      Select 'Stage 2A',  't0',    'n1',    'm0' Union All 
      Select 'Stage 2A',  't1',    'n1',    'm0' Union All 
      Select 'Stage 2A',  't2',    'n0',    'm0' Union All 
      Select 'Stage 2B',  't2',    'n1',    'm0' Union All 
      Select 'Stage 2B',  't3',    'n0',    'm0' Union All 
      Select 'Stage 3A',  't0',    'n2',    'm0' Union All 
      Select 'Stage 3A',  't1',    'n2',    'm0' Union All 
      Select 'Stage 3A',  't2',    'n2',    'm0' Union All 
      Select 'Stage 3A',  't3',    'n1',    'm0' Union All 
      Select 'Stage 3A',  't3',    'n2',    'm0'    
    )
Select      t.id, t.T_cat as tumour_stage, t.N_cat as node_stage, t.M_cat as met_stage, 
            Case When t.M_cat = 'm1' Then 'Stage 4' 
                 When t.N_cat = 'n3' And t.M_cat = 'm0' Then 'Stage 3C'
                 When t.T_cat = 't4' And t.M_cat = 'm0' Then 'Stage 3B'
                 When s.overall_stage Is Not Null Then s.overall_stage
            Else 'N/A'
            End as overall_stage
From        stages t
Left Join   stage_names s ON( s.T_category = t.T_cat And 
                              s.N_category = t.N_cat And 
                              s.M_category = t.M_cat )
Order By    t.id;
SELECT * FROM tnm_staging;  -- this should resut with  40 different combinations each with it's own overall_stage following your rules

... и с вашей таблицей патологий и данными как:

CREATE TABLE pathology ( pathology_id VARCHAR(100) NOT NULL PRIMARY KEY,              
                           tumour_stage ENUM('t0','t1', 't2', 't3', 't4'),
                           node_stage ENUM('n0', 'n1', 'n2', 'n3'),
                           met_stage ENUM('m0', 'm1')
                         );
--    S a m p l e    D a t a :
pathology_id    tumour_stage    node_stage  met_stage
------------    ------------    ----------  ---------
01              t0              n0          m0
02              t0              n1          m0
03              t0              n2          m0
04              t0              n2          m1
05              t1              n0          m0
06              t1              n1          m0
07              t1              n2          m0
08              t3              n1          m0
09              t3              n1          m1
10              t3              n3          m0
11              t4              n2          m0
12              t4              n3          m0
13              t2              n1          m0

... объедините свои таблицы патологии и tnm_staging, чтобы получить столбец overal_stage для каждой строки в таблице патологии:

--      S Q L : 
Select      t.pathology_id, t.tumour_stage, t.node_stage, t.met_stage, 
            s.overall_stage
From        pathology t
Left Join   tnm_staging s ON( s.tumour_stage = t.tumour_stage And 
                              s.node_stage = t.node_stage And 
                              s.met_stage = t.met_stage )
Order By    t.pathology_id

Посмотрите скрипт здесь (с результатами).

Фантастическое спасибо вам огромное. Теперь я могу этому научиться на основе реверс-инжиниринга. Я только что добавил дополнительные поля и данные в таблицу патологии вместе с уже имеющимися данными tnm. Огромное вам спасибо за вашу помощь и за то, что вы поддерживаете новичка на этом сайте, а также за MySQL.

Donna Cannon 03.09.2024 18:47

@DonnaCannon Пожалуйста. Рад помочь.

d r 03.09.2024 19:01

Другие вопросы по теме