Как вернуть предмет (если он существует) желательно поверх другого? - PullRequest
1 голос
/ 02 мая 2019

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

Вот как выглядят таблицы (они не могут быть изменены):

CREATE TABLE Clients
(
    id_client int PRIMARY KEY, /* client's id */
    nm_client varchar(200), /* client's name */
    zipcode int
);

CREATE TABLE PhoneType
(
    cd_phoneType int PRIMARY KEY, /* 1 for landline 2 for cellphone */
    nm_phoneType varchar(60) /* "Landline" if the above is 1 or "Cellphone" if 2*/
);

CREATE TABLE Phones
(
    cd_phone int PRIMARY KEY,
    cd_phoneType int, /* 1 for landline 2 for cellphone */
    nu_phone VARCHAR(20), /* phone number */
    id_client INT, /* client's id */
    FOREIGN KEY (cd_phoneType) REFERENCES PhoneType(cd_phoneType)
    FOREIGN KEY (id_client) REFERENCES Clients(id_client)
);

В основном, если cd_phoneType = 2 для клиента, он должен вернуть номер его мобильного телефона, в противном случае вернуть его другой номер.Как мне сделать это в синтаксисе SQL?

Вот исходный код, который я сделал:

SELECT nm_client, nm_phoneType, nu_phone 
FROM Clients
JOIN Phones ON Clients.id_client = Phones.id_client
JOIN PhoneType ON PhoneType.cd_phoneType = Phones.cd_phoneType;

Ответы [ 2 ]

1 голос
/ 02 мая 2019

Во-первых, давайте превратим данные из «2 строк по одному телефонному номеру на каждого клиента» в «одну строку из 2 столбцов телефонных номеров на клиента»

SELECT 
  nm_client,
  MAX(CASE WHEN nm_phoneType = 1 THEN nu_phone END) as landline,
  MAX(CASE WHEN nm_phoneType = 2 THEN nu_phone END) as mobile
FROM Clients
JOIN Phones
ON Clients.id_client = Phones.id_client
GROUP BY nm_client

Когда вы увидите, как это работает, теперьВы можете использовать COALESCE, функцию, которая работает через список аргументов слева направо и возвращает первый найденный ненулевой аргумент:

SELECT
  nm_client,
  COALESCE(
    MAX(CASE WHEN nm_phoneType = 2 THEN nu_phone END),
    MAX(CASE WHEN nm_phoneType = 1 THEN nu_phone END)
  ) as pref_num
FROM Clients
JOIN Phones
ON Clients.id_client = Phones.id_client
GROUP BY nm_client

-

Если вы только когда-либовыбирая одного клиента за раз, ярлык может быть достигнут с помощью TOP ORDER BY:

SELECT TOP 1
  nm_client,
  nu_phone
FROM Clients
JOIN Phones
ON Clients.id_client = Phones.id_client
WHERE clients.id_client = 1234
ORDER BY nm_phonetype DESC --prefer 2 over 1
0 голосов
/ 02 мая 2019

Использование APPLY:

SELECT c.nm_client, c.nm_phoneType, p.nu_phone 
FROM Clients c OUTER APPLY
     (SELECT TOP (1) p.*
      FROM Phones p
      WHERE c.id_client = p.id_client
      ORDER BY (CASE WHEN p.cd_phoneType = 2 THEN 1 ELSE 2 END)
     );

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

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