Intereting Posts
Конкатенат (клей), где условия OR или AND (Arel, Rails3) sql – вставка в несколько таблиц в одном запросе java.sql.SQLException: Слишком мало параметров. Ожидаемые 2 Вставить несколько записей в oracle Transact-SQL – дополнительный запрос или левое соединение? Как присоединиться к таблицам в regex Создать новый столбец, если заявление, основанное на повторяющихся строках в R Операция не разрешена после закрытия ResultSet (mysql, java) что такое использование аннотаций @Id и @GeneratedValue (strategy = GenerationType.IDENTITY)? Почему тип генерации идентичен? просмотр SQL, выполненный отчет Jasper ORA-01839 "дата не действительна для указанного месяца" для to_date в разделе where Разница между языком sql и языком plpgsql в функциях PostgreSQL MySQL Где DateTime больше, чем сегодня Как сгруппировать эти данные, чтобы я мог вытащить определенные строки из каждой группы Как создать таблицу или запрос перекрестных ссылок для моих данных?

Расширенный фильтр в SQL

У меня проблема с фильтрацией в моем SQL. Пожалуйста, взгляните на схему базы данных.

введите описание изображения здесь

Теперь я хотел бы получить программистов, которые знают PHP с навыками ●● / ●●● и Java с навыками ●●●. Я выполнил следующий запрос:

SELECT p.name, p.city FROM programmers p INNER JOIN skills s ON p.id = s.programmer WHERE ( s.lang = 'PHP' AND s.level > 1 ) OR ( s.lang = 'Java' AND s.level = 3 ); 

У меня есть

  • Джошуа, Атланта (потому что Java = 3)
  • Джошуа, Атланта (потому что PHP> 1)
  • Кристофер, Чикаго (потому что PHP> 1)

Но Кристофер не знает Java, но он возвращается. Замена OR с помощью AND между основными условиями не приводит к возврату ничего.

Более того, я хочу получить все навыки программиста в одной строке; здесь Джошуа находится в двух отдельных рядах. Как это исправить?

Все рассмотрено, последние вопросы. Как получить:

  • программисты с навыками PHP ●● / ●●●, JS ●●● и HTML ● / ●● / ●●●
  • программисты с навыками PHP ●● / ●●● и PHP опыт 2+ лет и JS ●●● с опытом 4+ лет
  • программисты с навыками PHP ● / ●● / ●●● и JS ●●● с опытом как минимум 3+ лет в обоих

Надеюсь, это возможно. Заранее спасибо.


EDIT Операции, ориентированные на даты, не являются проблемой, и нет необходимости вычислять разницу между датами, SQL может содержать только год, то есть 2010 год. Обычно дата не является точкой.

Это пример проблемы с множеством наборов. Мне нравится решать их с помощью агрегации и having :

 SELECT p.name, p.city FROM programmers p INNER JOIN skills s ON p.id = s.programmer GROUP BY p.name, p.city HAVING SUM( s.lang = 'PHP' AND s.level > 1 ) > 0 AND SUM( s.lang = 'Java' AND s.level = 3 ) > 0; 

РЕДАКТИРОВАТЬ:

Если вам нужен список навыков (который не был частью исходного вопроса), используйте group_concat() :

 SELECT p.name, p.city, group_concat(s.lang, ':', s.level separator '; '); FROM programmers p INNER JOIN skills s ON p.id = s.programmer GROUP BY p.name, p.city HAVING SUM( s.lang = 'PHP' AND s.level > 1 ) > 0 AND SUM( s.lang = 'Java' AND s.level = 3 ) > 0; 

Это даст вам то, что вы хотите, но это совсем не гибко.

 select p.name, p.city, php.lang, php.level, j.lang, j.level from programmer p join skills php on php.programmer = p.id join skills j on j.programmer = p.id where php.lang = 'PHP' and php.level > 1 and j.lang = 'Java' and j.level = 3; 

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

 create view JavaSkills as select programmer, lang, level, exp_from from skills where lang = 'Java' 

Тогда запрос будет

 select p.name, p.city, php.lang, php.level, j.lang, j.level from programmer p join PhpSkills php on php.programmer = p.id join JavaSkills j on j.programmer = p.id where php.level > 1 and j.level = 3; 

План выполнения должен выглядеть аналогичным, если не идентичным, но запрос немного легче читать. Это также неудобно поддерживать, но каждый делает то, что можно. 😉