Nano Hash - криптовалюты, майнинг, программирование

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

Таблицы, над которыми я работаю, содержат сведения об их лечении и сведения о приемах, которые называются vwTreatmentPlans и vwAppointmentDetails соответственно.

Моя цель - вернуть только одну строку для каждого кода пациента. Я хочу, чтобы он отображал два столбца: код пациента из таблицы vwTreatmentPlans и назначениеDateTimevalue из таблицы vwAppointmentDetails. САМОЕ ВАЖНОЕ, везде, где есть более одной строки встречи, я хочу, чтобы отображались только последние сведения о встрече, поэтому:

vA.appointmentDateTimevalue Desc

Используя предложения AND, возвращается только одна строка для каждого PatientCode, чего я и хочу. Однако существует проблема отношения «многие к одному» между кодами пациентов из двух таблиц.

SELECT
    vT.PatientCode, MAX(vA.appointmentDateTimevalue)
FROM vwTreatmentPlans vT
    INNER JOIN vwAppointmentDetails vA ON vT.PatientCode = vA.patientcode
WHERE
    vT.PatientCode IN ( 123)
AND
    vT.[Current] = 1
AND
    vT.Accepted = 1
GROUP BY vT.PatientCode, vA.appointmentDateTimevalue
ORDER by vT.PatientCode, vA.appointmentDateTimevalue Desc

Например, один код пациента возвращает следующий результат:

PatientCode   appointmentDateTimevalue
123           2016-02-01 09:10:00.000
123           2016-01-07 09:15:00.000
123           2015-12-31 10:40:00.000

Итак, для приведенного выше примера мне нужен этот вывод:

PatientCode   appointmentDateTimevalue
123           2016-02-01 09:10:00.000

Если бы было выбрано более одного кода пациента, я бы хотел:

PatientCode   appointmentDateTimevalue
123           2016-02-01 09:10:00.000
456           2016-04-11 15:45:00.000

Я пробовал возиться с вложенными выборками, предложениями и т. д. и, честно говоря, понятия не имел. Я был бы очень признателен за помощь с чем-то, что должно быть разочаровывающе простым!

Спасибо.


  • Не группировать по vA.appointmentDateTimevalue 11.01.2016
  • Какую СУБД вы используете? 11.01.2016
  • Я считаю, что это SQL Server. 12.01.2016

Ответы:


1

Почему вы группируете по vA.appointmentDateTimevalue? Вам не нужно этого делать. Таким образом, вы можете получить свой набор результатов со следующим запросом

SELECT
    vT.PatientCode, 
    MAX(vA.appointmentDateTimevalue) as max_date
FROM vwTreatmentPlans vT
    INNER JOIN vwAppointmentDetails vA ON vT.PatientCode = vA.patientcode
WHERE vT.[Current] = 1
         AND vT.Accepted = 1
GROUP BY vT.PatientCode
ORDER BY vt.patientCode
11.01.2016
  • Вы знаете, я действительно задавался вопросом об этом. Я предполагаю, что в отчаянии я знал, что должен что-то сделать с назначениемDateTimevalue, но не был уверен, что именно. Ваш код работает кстати! Спасибо. 12.01.2016

  • 2

    Все данные, которые вы показываете (PatientCode и appointmentDateTimevalue), доступны в таблице vwAppointmentDetails. Так что выбирайте из этой таблицы.

    Критерии выбора записей находятся в таблице vwTreatmentPlans, поэтому они должны быть в предложении where.

    select patientcode, max(appointmentdatetimevalue)
    from vwappointmentdetails
    where patientcode in
    (
      select patientcode
      from vwtreatmentplans
      where patientcode in (123, ...)
      and current = 1
      and accepted = 1
    )
    group by patientcode;
    

    Не надо присоединяться сюда. Это делает запрос очень удобным для чтения и сопровождения. Разочаровывающе просто? :-)

    11.01.2016
  • Это не проще и не эффективнее соединения 12.01.2016
  • @Frisbee: это это проще. Вы читаете только из таблицы, из которой хотите прочитать данные. Попробуйте COUNT(*) с обоими запросами :-) Соединения могут стать проблемой при агрегировании данных, особенно для новичков, которые еще не привыкли к объединению предварительно агрегированных данных. Поскольку нас интересует только наличие данных в vwtreatmentplans, мы должны использовать EXISTS или IN. Правило: Пишите вопросы так, как вы бы сформулировали задачу. Присоединение к таблице только для того, чтобы гарантировать существование записей, только запутает запрос. Здесь это не имеет большого значения, потому что запрос небольшой, но обычно становится более важным с большими запросами. 12.01.2016
  • ОК, это проще для тебя. Ни в коем случае не более эффективно. Этот запрос по-прежнему считывает данные из двух таблиц. ИН не эффективен. И count(*) как бы путается с group by. И OP уже использует объединение, поэтому явно не путается с этим синтаксисом. SELECT vA.PatientCode, MAX(vA.appointmentDateTimevalue) точно такой же - вы думаете, что это будет иметь значение? 12.01.2016
  • Чтобы не усложнять вопрос, я не упомянул тот факт, что хотел иметь возможность ВЫБИРАТЬ дополнительные столбцы из таблицы vwTreatmentPlans. Вот почему я хотел сохранить соединение. Извините, если это вообще запутало. Однако ваша точка зрения очень верна, и я ее рассмотрел. В будущем я не буду пропускать подобные вещи из своих постов. 12.01.2016

  • 3

    группируясь на обоих вы убиваете макс

    SELECT vT.PatientCode, MAX(vA.appointmentDateTimevalue)
      FROM vwTreatmentPlans vT
      JOIN vwAppointmentDetails vA 
            ON vT.PatientCode = vA.patientcode
           AND vT.PatientCode in (123)
           AND vT.[Current]   = 1
           AND vT.Accepted    = 1
     GROUP BY vT.PatientCode 
     ORDER by vT.PatientCode 
    
    11.01.2016
  • Как и ответ fabulaspb, этот код также на деньги. Спасибо, что нашли время, чтобы помочь мне! 12.01.2016

  • 4

    Вам дали правильные ответы, но есть еще одна вещь, на которую я хотел бы указать:

    В своем ответе на мой другой ответ вы говорите: «... что я хотел иметь возможность ВЫБРАТЬ дополнительные столбцы из таблицы vwTreatmentPlans». Но в этой таблице может быть много записей для одного кода пациента. Если ваши критерии (принято = 1 и текущий = 1) гарантируют, что вы получите только одну запись для каждого кода пациента, тогда нет проблем. Однако, если вы все еще можете получить более одной записи, вам придется выбрать агрегированные данные из этой таблицы (например, минимальное значение или сумму). Это может усложниться из-за большого количества записей для каждого кода пациента из обеих таблиц. Например, этот запрос даст вам неправильную сумму (поскольку значения будут умножены на количество совпадающих записей vA):

    SELECT
      vT.PatientCode, 
      MAX(vA.appointmentDateTimevalue) as max_date,
      SUM(vT.amount) as total_amount
    FROM vwTreatmentPlans vT
    INNER JOIN vwAppointmentDetails vA ON vT.PatientCode = vA.PatientCode
    WHERE vT.Current = 1
      AND vT.Accepted = 1
    GROUP BY vT.PatientCode
    ORDER BY vt.PatientCode;
    

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

    SELECT
      vT.PatientCode, 
      vA.max_date,
      vT.total_amount
    FROM 
    (
      SELECT PatientCode, SUM(amount) as total_amount
      FROM vwTreatmentPlans
      WHERE Current = 1
        AND Accepted = 1
      GROUP BY PatientCode
    ) vT
    INNER JOIN 
    (
      SELECT PatientCode, MAX(appointmentDateTimevalue) as max_date
      FROM vwAppointmentDetails
      GROUP BY PatientCode
    ) vA ON vT.PatientCode = vA.PatientCode
    ORDER BY vt.PatientCode;
    
    12.01.2016

    5

    @Торстен Кеттнер

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

    SELECT
        vT.PatientCode,
        vA.NextAppointmentDate,
        DefProvInis,
        UDAs
    FROM
    (
        SELECT PatientCode, MAX(TPNumber) as TPNumber, MIN(DefaultProviderInitials) as DefProvInis, MAX(UDAS) as UDAs
        FROM vwTreatmentPlans
        WHERE PatientCode in (
            1000001
            ,24001841
            ,20032285
            )
        AND [Current] = 1
        AND Accepted = 1
        GROUP BY PatientCode
    ) vT
    INNER JOIN
    (
        SELECT PatientCode, MAX(appointmentDateTimevalue) as NextAppointmentDate
        FROM vwAppointmentDetails
        GROUP BY PatientCode
    ) vA ON vA.PatientCode = vT.PatientCode
    ORDER BY vA.PatientCode
    

    Мне также нужно знать столбцы DefaultProviderInitials и UDAS. Я думаю, что мои результаты точны, даже несмотря на то, что я выделяю им MIN() и MAX() (казалось, что это не имеет значения в любом случае), хотя это беспорядочно.

    12.01.2016
    Новые материалы

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

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

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..