2014-09-25 2 views
0
Table A      Table B 
ID  Name     ID  Name Last_Name 
1  John     1  John Depp 
2  Henry     2  David Henry 
3  Ken 

Я стараюсь, чтобы выбрать имя в заявлении с этим условием:Выберите заявление с внутренним соединением

  1. Если NAME в TableA состояния карты с NAME в TableB, затем выберите Last_Name
  2. Если NAME является TableA равно LAST_NAME в TableB, затем выберите NAME из TableA
  3. Если NAME в TableA в не в состоянии отобразить с TableB «s NAME или LAST_NAME, затем выберите NAME из TableA.

метод я использовал:

SELECT * FROM 
(SELECT A.ID NO, LAST_NAME REALNAME 
FROM TABLEA A 
INNER JOIN TABLEB B 
ON A.NAME = B.NAME 
    UNION ALL 
SELECT A.ID NO, A.NAME REALNAME 
FROM TABLEA A 
WHERE EXISTS (SELECT 1 FROM TABLEB B WHERE A.NAME = B.LAST_NAME) 
    UNION ALL 
SELECT A.ID NO, A.NAME REALNAME 
FROM TABLEA A 
WHERE NOT EXISTS (SELECT 1 FROM TABLEB B WHERE A.NAME = B.NAME OR A.NAME = B.LAST_NAME) 
)AS T 

ВОПРОС: Это больше упростить запрос, я могу использовать, чтобы достичь условий?

+0

Являются ли идентификаторы между двумя надежными родственниками? –

ответ

2

вы можете использовать случай, чтобы более читаемым

SELECT A.ID NO, CASE WHEN A.Name = B.Name THEN B.LAST_NAME 
        WHEN A.Name = B.LAST_NAME THEN A.NAME 
        WHEN A.Name = B.Name AND A.Name = B.LAST_NAME THEN A.NAME END AS REALNAME 
FROM TABLEA A, TABLEB B 
0

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

select a.id, b.last_name as realname 
    from tablea a 
    join tableb b 
    on a.name = b.name 
union all 
select distinct a.id, a.name 
    from tablea a 
    join tableb b 
    on a.name = b.last_name 
union all 
select a.id, a.name 
    from tablea a 
    left join tableb b 
    on a.name = b.name 
    or a.name = b.last_name 
where b.name is null 
+0

Обратите внимание, что если 'last_name' не уникально в' tableb', второй 'SELECT' в этом выражении может возвращать * больше * строк, чем это делает исходный запрос. – spencer7593

+0

@ spencer7593 true, поэтому я просто добавил отличный от адреса, что –

+0

@BrianDeMilla: добавление ключевого слова 'DISTINCT' должно быть прекрасно разрешено до тех пор, пока' tuple уникален в TABLEA. (Нормативный шаблон для уникального ограничения на 'id', а в образцовых данных не отображаются дубликаты. Заметим, что нам не дана явная гарантия того, что' (id, name) 'уникален.) – spencer7593

0

Да, вы может сделать ваше заявление «более четким», форматируя его. Это также яснее для читателя, если вы избегаете повторного использования одного и того же псевдонима таблицы (также облегчает сопоставление EXPLAIN с statemnt). Кроме того, если вы используете строчные буквы для псевдонимов таблиц и имен столбцов и квалифицируете ВСЕ ссылки столбцов. Кроме того, устранение ненужного встроенного представления также облегчит чтение инструкции.

Это функционально эквивалентно исходное заявление, но это «понятнее»

SELECT a.id  AS `NO` 
     , b.last_name AS `REALNAME` 
     FROM TABLEA a 
     JOIN TABLEB b 
     ON a.name = b.name 
    UNION ALL 
    SELECT e.id  AS `NO` 
     , e.name  AS `REALNAME` 
     FROM TABLEA e 
    WHERE EXISTS 
      (SELECT 1 FROM TABLEB f WHERE f.last_name = e.name) 
    UNION ALL 
    SELECT o.id  AS `NO` 
     , o.name  AS `REALNAME` 
     FROM TABLEA o 
    WHERE NOT EXISTS 
      (SELECT 1 FROM TABLEB p WHERE o.name IN (p.name,p.last_name)) 

(я бы тоже предпочел нижний регистр для tablenames, но ваша система может быть настроена для использования с учетом регистра имен таблиц . Было бы также более ясным, если бы названия таблиц были менее двусмысленными.)

Предикат NOT EXISTS в последнем SELECT может быть заменен шаблоном антисоединения; что будет «яснее» ... для тех, кто знаком с шаблоном антисоединения и возможностью его выбора, может быть. Непосвященному, вероятно, нет, и NOT EXISTS понятнее.)

Смежные вопросы