2016-01-09 2 views
5

Вопрос заключается в том,SQL: 4 условия в сочетании с ИЛИ

Определить названия всех кораблей в таблице Ships, которые удовлетворяют комбинацию, по меньшей мере, четырех критериев из следующего списка: numGuns = 8 расточки = 15 смещение = 32000 type = bb launch = 1915 class = Kongo country = USA.

Я нашел ответ для этого упражнения.

Ответ,

SELECT s.name from ship s,classes c 
WHERE s.class=c.class AND 
    ((numGuns = 8 AND bore = 15 AND displacement = 32000 AND type = 'bb') 
     OR (numGuns = 8 AND bore = 15 AND displacement = 32000 AND launched = 1915) 
     OR (numGuns = 8 AND bore = 15 AND displacement = 32000 AND c.class = 'Kongo') 
     OR (numGuns = 8 AND bore = 15 AND displacement = 32000 AND country = 'USA') 
     OR (numGuns = 8 AND bore = 15 AND type = 'bb' AND launched = 1915) 
     OR (numGuns = 8 AND bore = 15 AND type = 'bb' AND c.class = 'kongo') 
     OR (numGuns = 8 AND bore = 15 AND type = 'bb' AND country = 'USA') 
     OR (numGuns = 8 AND bore = 15 AND launched = 1915 AND c.class = 'Kongo') 
     OR (numGuns = 8 AND bore = 15 AND launched = 1915 AND country = 'USA') 
     OR (numGuns = 8 AND bore = 15 AND c.class = 'Kongo' AND country = 'USA') 
     OR (numGuns = 8 AND displacement = 32000 AND type = 'bb' AND launched = 1915) 
     OR (numGuns = 8 AND displacement = 32000 AND type = 'bb' AND c.class = 'kongo') 
     OR (numGuns = 8 AND displacement = 32000 AND type = 'bb' AND country = 'USA') 
     OR (numGuns = 8 AND displacement = 32000 AND launched = 1915 AND c.class = 'Kongo') 
     OR (numGuns = 8 AND displacement = 32000 AND launched = 1915 AND country = 'USA') O 

Мой вопрос,

Есть ли другой простой способ проверить условия.

+1

Пожалуйста, дайте содержательный заголовок. –

+1

Да, просто перемещайте свои предложения WHERE, чтобы упростить их. – Ruslan

+0

@Ruslan Что означает? –

ответ

4

Бросок от boolean до integer выходов 0 или 1:

select s.name 
from 
    ship s 
    inner join 
    classes c using (class) 
where 
    (numguns = 8)::int + 
    (bore = 15)::int + 
    (displacement = 32000)::int + 
    (type = 'bb')::int + 
    (launched = 1915)::int + 
    (class = 'Kongo')::int + 
    (country = 'USA')::int 
    >= 4 
1

Строго с предикативной точки зрения, да, например, последние 5 предикатов:

OR (numGuns = 8 AND displacement = 32000 AND type = 'bb' AND launched = 1915) 
OR (numGuns = 8 AND displacement = 32000 AND type = 'bb' AND c.class = 'kongo') 
OR (numGuns = 8 AND displacement = 32000 AND type = 'bb' AND country = 'USA') 
OR (numGuns = 8 AND displacement = 32000 AND launched = 1915 AND c.class = 'Kongo') 
OR (numGuns = 8 AND displacement = 32000 AND launched = 1915 AND country = 'USA') 

может быть:

OR ((numGuns = 8 AND displacement = 32000) AND 
    ((type = 'bb' AND launched = 1915) OR 
    (type = 'bb' AND c.class = 'kongo') OR 
    (type = 'bb' AND country = 'USA') OR 
    (launched = 1915 AND c.class = 'Kongo') OR 
    (launched = 1915 AND country = 'USA'))) 
2

Вы можете использовать CASE WHEN заявление для подсчета числа совпадающих столбцов для каждого запись, а затем оберните этот запрос, чтобы получить только записи с 4 или более соответствующими столбцами.

SELECT t.name 
FROM 
(
    SELECT s.name, 
     CASE WHEN s.numGuns = 8 THEN 1 ELSE 0 END AS c1, 
     CASE WHEN s.dbore = 15 THEN 1 ELSE 0 END AS c2, 
     CASE WHEN s.displacement = 32000 THEN 1 ELSE 0 END AS c3, 
     CASE WHEN s.type = 'bb' THEN 1 ELSE 0 END AS c4, 
     CASE WHEN s.launched = 1915 THEN 1 ELSE 0 END AS c5, 
     CASE WHEN c.class = 'Kongo' THEN 1 ELSE 0 END AS c6, 
     CASE WHEN s.country = 'USA' THEN 1 ELSE 0 END AS c7 
    FROM ship s INNER JOIN classes c ON s.class = c.class 
) t 
WHERE (t.c1 + t.c2 + t.c3 + t.c4 + t.c5 + t.c6 + t.c7) >= 4 
Смежные вопросы