Выберите строку в зависимости от различных условий

Моя исходная таблица выглядит примерно так, как показано ниже enter image description here

Это промежуточный шаг enter image description here

И окончательный результат должен выглядеть так, как показано ниже enter image description here

Обычно сначала мне нужно SELECT, самый низкий Rank для PERSONID, AddressID и PhoneType. Если есть несколько строк с одним и тем же Rank, мне нужно вернуть тот, у которого когда-либо был максимальный VerificationDate, а затем получить окончательный результат.

Создать выписку:

CREATE TABLE AddressPhone ([PERSONID] [varchar](10) NOT NULL,
                           [AddressID] [int] NOT NULL,
                           [PhoneType] [varchar](2) NOT NULL,
                           [PhoneNumber] [varchar](15) NOT NULL,
                           [VerificationDate] [datetime] NOT NULL,
                           [Rank] [int] NOT NULL) ON [PRIMARY];

Большинству людей здесь нужен форматированный текст, а не изображения (или ссылки на изображения).

jarlh 10.08.2018 16:56

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

Sunil 10.08.2018 17:00

ТАК - ерунда с таблицами, но есть генераторы, чтобы помочь с этим.

Jeroen Mostert 10.08.2018 17:02

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

sniperd 10.08.2018 17:03

При редактировании записывайте значения в соответствующие столбцы. Затем отметьте текст и щелкните {}.

jarlh 10.08.2018 17:04

Вы также можете анонимизировать эти номера телефонов.

HoneyBadger 10.08.2018 17:06

Комментарии не принимают форматированный текст. Вам нужно поместить данные в свой вопрос по редактирование. Я сделал это за вас для вашего оператора CREATE (и исправил синтаксические ошибки), однако убедитесь, что вы сделали это для своего оператора INSERT.

Larnu 10.08.2018 17:11

@Sunil Что ты пробовал до сих пор ??? Прочитайте это. stackoverflow.com/help/how-to-ask

Eric 10.08.2018 17:57
0
8
60
1

Ответы 1

Попробуйте этот запрос:

Пример данных (не то же самое, но эквивалентно):

declare @tbl table (personid int, addressid int, phonetype bit, phonenumber int, verificationdate date, rank int);
insert into @tbl values
(1, 1, 0, null, '2014-06-24', 4),
(1, 1, 1, null, '2014-06-24', 4),
(1, 1, 1, null, '2014-06-24', 4),
(1, 1, 1, null, '2014-06-24', 4),
(1, 1, 1, null, '2014-06-24', 4),
(1, 1, 0, null, '2014-06-24', 4),
(1, 1, 0, null, '2014-06-24', 3),
(1, 1, 0, null, '2014-06-24', 4),
(1, 1, 1, null, '2014-06-24', 2),
(1, 1, 1, null, '2014-06-24', 1),
(1, 1, 0, null, '2014-06-24', 4),
(1, 1, 1, null, '2014-06-24', 4),

(2, 2, 0, null, '2014-06-24', 2),
(2, 2, 0, null, '2014-06-24', 1),
(2, 2, 0, null, '2014-06-24', 4),
(2, 2, 1, null, '2014-06-25', 1),
(2, 2, 1, null, '2014-06-24', 1);

--intermediate step
select personid, addressid, phonetype, phonenumber, verificationdate, rank,
       row_number() over (partition by rank order by verificationdate) rnVerDate
from (
    select personid, addressid, phonetype, phonenumber, verificationdate, rank,
           row_number() over (partition by personid, addressid, phonetype order by rank desc) rnRank
    from @tbl
) a where rnRank = 1

--final result
select personid, addressid, phonetype, phonenumber, verificationdate, rank
from (
    select personid, addressid, phonetype, phonenumber, verificationdate, rank,
           row_number() over (partition by rank order by verificationdate) rnVerDate
    from (
        select personid, addressid, phonetype, phonenumber, verificationdate, rank,
               row_number() over (partition by personid, addressid, phonetype order by rank desc) rnRank
        from @tbl
    ) a where rnRank = 1
) a where rnVerDate = 1

Привет, Михал. Спасибо за запрос, но я не получаю желаемого результата. Вывод, который я получаю, представляет собой столбцы ниже, а не окончательный вывод выше PERSONID, ADDRESSID, PHONETYPE, PHONENUMBER, VERIFICATION DATE, RANK, и я получаю только одну запись для КОМБИНАЦИИ PERSONID ADDRESSID.

Sunil 10.08.2018 17:44

Когда я меняю ранг desc на ранжирование asc в приведенном выше запросе, тогда для одной комбинации PERSONID ADDRESSID я получаю две записи: одну с рангом 1 и одну с рангом 4, но когда оно было desc, я получал только одну запись с рангом 4

Sunil 10.08.2018 17:51

@Sunil Я получаю правильный результат с вашими данными. В любом случае, если ответ вам помог, принимайте его :)

Michał Turczyn 10.08.2018 17:54

О, Михал, определенно твой вопрос мне помог. Этот факт нельзя отрицать. Я принимаю это и благодарен вам за то же самое.

Sunil 10.08.2018 17:58

@Sunil Я счастлив, что смог помочь. Я имел в виду принять, поставив зеленую отметку слева от ответа :)

Michał Turczyn 10.08.2018 17:59

@ MichałTurczyn I meant accepting by checking green mark га! Мне это нравится :) :) Вы заслужили мой голос!

sniperd 10.08.2018 18:08

@Michal Я бы не прочь поставить зеленую отметку, но не хочу показаться грубым. Если вы видите 3 изображения над средним, это то, что мы получили после того, как я внес изменения в запрос, как показано ниже. Однако я не получаю 2 строки для второго раздела в примере, который вы предоставили выше.

Sunil 10.08.2018 18:15

строки для второго раздела в приведенном выше примере. select personid, addressid, phonetype, phonenumber, verifydate, rank from (select personid, addressid, phonetype, phonenumber, verifydate, rank, row_number () over (разделение в порядке ранжирования по дате проверки) rnVerDate from (select personid, addressid, phonetype, phonenumber , Verificationdate, rank, row_number () over (разделение по идентификатору пользователя, идентификатору адреса, порядку типов телефонов по рангу desc) rnRank от @tbl) a, где rnRank = 1) a, где rnVerDate = 1

Sunil 10.08.2018 18:18

Запрос работает именно так, как положено, я его проверил. Где-то у вас могут быть неправильные типы. Вы уверены, что verificationdate имеет тип datetime? Не похоже.

Michał Turczyn 10.08.2018 18:21

Настало время, когда я проверил свою базу данных. Excel не отформатировал его правильно. Хотел бы я как-нибудь связаться с вами :)

Sunil 10.08.2018 18:23

@ MichałTurczyn, позвольте мне подробно объяснить, используя образцы данных, которые вы предоставили. Из первого набора я должен получить две записи PERSONID - 1, ADRESSID - 1, phonetype - 0, phone number - null, дату проверки - 2014-06-24, rank - 3 и другую запись из первого набора PERSONID - 1, АДРЕСИД - 1, тип телефона - 1, номер телефона - ноль, дата проверки - 24.06.2014, ранг - 1

Sunil 10.08.2018 18:47

@ MichałTurczyn из второго набора это будет PERSONID - 2, ADRESSID - 2, phonetype - 0, номер телефона - null, дата проверки - 2014-06-24, ранг - 1, а вторая запись должна быть PERSONID - 2, ADRESSID - 2, тип телефона - 1, номер телефона - null, дата проверки - 25.06.2014, ранг - 1. Дайте мне знать, если вы согласны с этим

Sunil 10.08.2018 18:49

@ MichałTurczyn после получения этих 4 наборов записей мне нужно преобразовать их в 2 набора записей как. PERSONID - 1, ADRESSID - 1, Phone Nimnber - null, FaxNumber - null, Rank - 1,3, а другая запись - PERSONID - 2, ADRESSID - 2, hone Nimnber - null, FaxNumber - null, Rank - 1,1

Sunil 10.08.2018 18:51

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

Michał Turczyn 10.08.2018 19:08

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