Выделить отдельные строки по столбцам - PullRequest
0 голосов
/ 21 октября 2019

У меня есть следующая таблица

VacancyID  VacancyName  HourRate  MarketID
------------------------------------------
1          manager      15        NULL
2          manager      17        1
3          sales        9         NULL
           assistant
4          store keeper 12        NULL
5          store keeper 13        1
6          customer     10        NULL
           consultant   

VacancyID - уникальный идентификатор вакансии

VacancyName - название вакансии

HourRate - часовая ставка

MarketID - уникальный идентификатор рынка, на котором открыта вакансия. Есть отдельная таблица Markets, но для этого вопроса это не имеет значения.

Мне нужно выбрать все отдельные вакансии (по VacancyName) из приведенной выше таблицы для MarketID == 1. Но если какая-то вакансия не открывается вmarket 1, он должен быть взят из строки с MarketID == NULL

Таким образом, для MarketID == 1 результат должен выглядеть следующим образом:

VacancyID  VacancyName  HourRate  MarketID
------------------------------------------
2          manager      17        1
3          sales        9         NULL
           assistant
5          store keeper 13        1
6          customer     10        NULL
           consultant  

В MarketID не существует вакансий продавца-консультанта и консультанта клиента. == 1, поэтому они взяты из MarketID == NULL. (вакансии из строк с MarketID == NULL следует брать, когда такой вакансии нет для конкретного рынка)

Какую команду SQL следует использовать для достижения такого результата?

Примечание: База данныхнаходится на SQL Server 2017.

Ответы [ 3 ]

2 голосов
/ 21 октября 2019

Вы можете использовать подзапрос для фильтрации по MarketID с null или 1, а затем использовать row_number(), чтобы присвоить ранг каждой записи в группах записей, имеющих одинаковый VacancyName, в то время какпридание более низкого приоритета значениям null. Затем внешний запрос просто фильтрует верхнюю запись по каждой группе.

select VacancyID, VacancyName, HourRate, MarketID 
from (
    select 
        t.*,
        row_number() over(
            partition by VacancyName 
            order by coalesce(MarketID, 0) desc
        ) rn
    from mytable t
    where coalesce(MarketID, 1) = 1
) x
where rn = 1
order by VacancyID

Чтобы запросить другой MarketID, вам просто нужно изменить предложение where, запрос будет работать аналогичным образом (при условии, чточто n > 0):

where coalesce(MarketID, <n>) = <n> 

Демонстрация на DB Fiddle :

VacancyID | VacancyName         | HourRate | MarketID
--------: | :------------------ | -------: | -------:
        2 | manager             |       17 |        1
        3 | sales assistant     |        9 |     <em>null</em> 
        5 | store keeper        |       13 |        1 
        6 | customer consultant |       10 |     <em>null</em> 
0 голосов
/ 21 октября 2019

or и not exists, кажется, делают то, что вы хотите:

select t.*
from t
where marketID = 1 or
      (marketID is null and
       not exists (select 1
                   from t t2
                   where t2.VacancyName = t.VacancyName and 
                         t2.marketId = 1
                  )
       );

С индексом (VacancyName, MarketId), я ожидаю, что это будет иметь очень хорошую производительность для больших наборов данных

0 голосов
/ 21 октября 2019

попробуйте

SELECT T.* 
FROM Your_Table T INNER JOIN
(
    SELECT MAX(VacancyID) AS VacancyID, VacancyName 
    FROM Your_Table
    WHERE MarketID = 1
    GROUP BY VacancyName 
) X
ON T.VacancyID = X.VacancyID

UNION

SELECT T.* 
FROM Your_Table T 
WHERE VacancyName  NOT IN 
                        (
                            SELECT VacancyName 
                            FROM Your_Table
                            WHERE MarketID = 1
                        )  

AND MarketID IS NULL
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...