С Новым годом! Форум программистов, компьютерный форум, киберфорум
PHP: базы данных
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
 Аватар для alpex
603 / 578 / 103
Регистрация: 16.07.2012
Сообщений: 1,762

выборка join-where

10.02.2013, 10:42. Показов 1070. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
есть такая структура бд
Кликните здесь для просмотра всего текста
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
CREATE  TABLE IF NOT EXISTS `personnel`.`tbl_practice` (
  `id` TINYINT(1) NOT NULL AUTO_INCREMENT ,
  `practice` VARCHAR(100) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' NOT NULL ,
  PRIMARY KEY (`id`) )
ENGINE = InnoDB DEFAULT CHARSET=utf8;
 
CREATE  TABLE IF NOT EXISTS `personnel`.`tbl_personnel` (
  `id` INT(11) NOT NULL AUTO_INCREMENT ,
  `surname` VARCHAR(45) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' NOT NULL ,
  `name` VARCHAR(45) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' NOT NULL ,
  `patronymic` VARCHAR(45) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' NOT NULL ,
  `email` VARCHAR(150) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' NOT NULL ,
  `date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
  `practice_id` TINYINT(1) NULL ,
  `comment` TEXT CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' NULL DEFAULT NULL ,
  PRIMARY KEY (`id`) ,
  INDEX `fk_tbl_personnel_tbl_practice_idx` (`practice_id` ASC) ,
  CONSTRAINT `fk_tbl_personnel_tbl_practice`
    FOREIGN KEY (`practice_id` )
    REFERENCES `personnel`.`tbl_practice` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB DEFAULT CHARSET=utf8;
 
CREATE  TABLE IF NOT EXISTS `personnel`.`tbl_skill` (
  `id` TINYINT(1) NOT NULL AUTO_INCREMENT ,
  `skill` VARCHAR(100)CHARACTER  SET 'utf8' COLLATE 'utf8_general_ci' NOT NULL ,
  PRIMARY KEY (`id`) )
ENGINE = InnoDB DEFAULT CHARSET=utf8;
 
CREATE  TABLE IF NOT EXISTS `personnel`.`tbl_personnel_skill` (
  `personnel_id` INT(11) NOT NULL ,
  `skill_id` TINYINT(1) NOT NULL ,
  PRIMARY KEY (`personnel_id`, `skill_id`) ,
  INDEX `fk_tbl_personnel_has_tbl_skill_tbl_skill1_idx` (`skill_id` ASC) ,
  INDEX `fk_tbl_personnel_has_tbl_skill_tbl_personnel1_idx` (`personnel_id` ASC) ,
  CONSTRAINT `fk_tbl_personnel_skill_tbl_personnel1`
    FOREIGN KEY (`personnel_id` )
    REFERENCES `personnel`.`tbl_personnel` (`id` )
    ON DELETE CASCADE
    ON UPDATE RESTRICT,
  CONSTRAINT `fk_tbl_personnel_skill_tbl_skill1`
    FOREIGN KEY (`skill_id` )
    REFERENCES `personnel`.`tbl_skill` (`id` )
    ON DELETE CASCADE
    ON UPDATE RESTRICT)
ENGINE = InnoDB DEFAULT CHARSET=utf8;
 
INSERT INTO `personnel`.`tbl_practice`(`id`, `practice`)
    VALUES  (NULL, 'без опыта'),
            (NULL, 'до 1 года'),
            (NULL, '1-3 года'),
            (NULL, '3-5 лет'),
            (NULL, 'более 5 лет');
 
INSERT INTO `personnel`.`tbl_skill`(`id`, `skill`)
    VALUES  (NULL, 'менеджмент'),
            (NULL, 'программирование'),
            (NULL, 'тестирование'),
            (NULL, 'дизайн');
 
INSERT INTO `personnel`.`tbl_personnel`(`id`, `surname`, `name`, `patronymic`, `email`, `date`, `practice_id`, `comment`)
    VALUES  (NULL, 'Иванов', 'Иван', 'Иванович', 'ivan@site.com', NULL, 1, ''),
            (NULL, 'Петров', 'Петр', 'Петрович', 'petr@site.com', NULL, 2, 'художник'),
            (NULL, 'Сидоров', 'Сидор', 'Сидорович', 'sidor@site.com', NULL, 3, 'программист'),
            (NULL, 'Сергеев', 'Сергей', 'Сергеевич', 'sergey@site.com', NULL, 4, 'мастер на все руки');
 
INSERT INTO `personnel`.`tbl_personnel_skill`(`personnel_id`, `skill_id`)
    VALUES  (1, 1),
            (2, 4),
            (3, 2),
            (3, 3),
            (4, 2),
            (4, 3),
            (4, 4);


Добавлено через 55 секунд
вот так я выбираю все данные из нее
SQL
1
2
3
4
5
6
7
8
9
10
SELECT p.id, p.surname, p.name, p.patronymic, p.email, DATE(p.date) AS DATE, p.comment,
                    pr.practice, GROUP_CONCAT(s.skill SEPARATOR "<br />") AS skill
                FROM ' . $this->db->dbprefix('personnel') . ' AS p
                LEFT JOIN ' . $this->db->dbprefix('practice') . ' AS pr
                ON p.practice_id = pr.id
                LEFT JOIN ' . $this->db->dbprefix('personnel_skill') . ' AS ps
                ON p.id = ps.personnel_id
                LEFT JOIN ' . $this->db->dbprefix('skill') . ' AS s
                ON ps.skill_id = s.id
                GROUP BY p.id
Добавлено через 2 минуты
получается вот такая таблица (рис.1)
но когда я пытаюсь отфильтровать по навыкам, например выбрать только тех кто владеет навыком дизайн и программирование вот таким кодом
SQL
1
2
3
4
5
6
7
8
9
10
11
SELECT p.id, p.surname, p.name, p.patronymic, p.email, DATE(p.DATE) AS DATE, p.comment,
                    pr.practice, GROUP_CONCAT(s.skill SEPARATOR "<br />") AS skill
                FROM ' . $this->db->dbprefix('personnel') . ' AS p
                LEFT JOIN ' . $this->db->dbprefix('practice') . ' AS pr
                ON p.practice_id = pr.id
                LEFT JOIN ' . $this->db->dbprefix('personnel_skill') . ' AS ps
                ON p.id = ps.personnel_id
                LEFT JOIN ' . $this->db->dbprefix('skill') . ' AS s
                ON ps.skill_id = s.id
                WHERE ps.skill_id IN(2,4)
                GROUP BY p.id
Миниатюры
выборка join-where  
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
10.02.2013, 10:42
Ответы с готовыми решениями:

Выборка списка в join
Привет. Подскажите что использовать, что бы сделать выборку списка, используя join. Вот примерный запрос $sql = &quot;SELECT t1.*,t2.* ...

Выборка из нескольких таблиц с JOIN
всем привет. есть 3 таблицы. как правильно выбрать все классы для препода с id = 1(или с id = 2, c условием WHERE) и его...

LEFT JOIN и выборка из цикла
Есть таблица - категории - id - cat_name И таблица - Подкатегории - id - cat_id - sub_cat_name Нужно одним запросом...

11
 Аватар для alpex
603 / 578 / 103
Регистрация: 16.07.2012
Сообщений: 1,762
10.02.2013, 10:45  [ТС]
То получается выборка как на рис.2

Тюе выбирает все правильно, но в столбце навыки показываются только те навыки которые выбирались
Миниатюры
выборка join-where  
0
 Аватар для alpex
603 / 578 / 103
Регистрация: 16.07.2012
Сообщений: 1,762
10.02.2013, 10:54  [ТС]
А мне нужно что бы там показывались все навыки которыми владеет данный сотрудник, но производился отбор есть ли у него запрошенный навык

Т.е у Петрова показывается только дизайн, который мы запрашивали, но он владеет еще и менеджментом, а выводятся только те которые были в where

Добавлено через 2 минуты
Может кто то знает как решить данный вопрос?
0
1178 / 1128 / 94
Регистрация: 31.05.2012
Сообщений: 3,060
10.02.2013, 12:34
Первое что приходит в голову, это просто сделать два запроса. Первым выбрать ид всех юзеров, а вторым удже выбрать данные по ид юзеров.

Добавлено через 1 минуту
А ещё возможно поможет вложенный подзапрос. Вместо поля, вписать ещё один SELECT который будет выбирать все навыки для юзера, на него условие из where Не должно подействовать
1
 Аватар для Vovan-VE
13210 / 6599 / 1041
Регистрация: 10.01.2008
Сообщений: 15,069
10.02.2013, 12:41
Цитата Сообщение от alpex Посмотреть сообщение
MySQL
1
WHERE ps.skill_id IN(2,4)
MySQL
1
2
3
4
5
6
WHERE EXISTS(
  SELECT *
  FROM `personnel_skill`
  WHERE `p`.`id` = `personnel_id`
    AND `skill_id` IN (2, 4)
)
1
1178 / 1128 / 94
Регистрация: 31.05.2012
Сообщений: 3,060
10.02.2013, 12:48
А это будет лучше работать чем просто выборка ид и подстановка в запрос?
то есть
SQL
1
2
3
4
5
6
WHERE `id` IN (
  SELECT `id`
  FROM `personnel_skill`
  WHERE `p`.`id` = `personnel_id`
    AND `skill_id` IN (2, 4)
)
1
 Аватар для Vovan-VE
13210 / 6599 / 1041
Регистрация: 10.01.2008
Сообщений: 15,069
10.02.2013, 13:00
Цитата Сообщение от DrobyshevAlex Посмотреть сообщение
А это будет лучше работать чем просто выборка ид и подстановка в запрос?
Не уверен на 100%. В таких слаучаях смотрю EXPLAIN.
См. также http://dev.mysql.com/doc/refma... eries.html
1
 Аватар для alpex
603 / 578 / 103
Регистрация: 16.07.2012
Сообщений: 1,762
10.02.2013, 13:37  [ТС]
спасибо, кажется то что нужно

Добавлено через 22 минуты
да работает как часы

Добавлено через 2 минуты
но вот только с IN запрос работал как и старый , может я конечно где то не то писал, а с EXISTS так как нужно, и я вместо * поставил id там
0
 Аватар для Vovan-VE
13210 / 6599 / 1041
Регистрация: 10.01.2008
Сообщений: 15,069
10.02.2013, 14:50
Цитата Сообщение от alpex Посмотреть сообщение
а с EXISTS так как нужно, и я вместо * поставил id там
Роли не играет. Оно умное, оно сображает, что EXISTS лишь проверяет наличие записей (или отсутствие, если NOT EXISTS), а не извлекает инфу в подном объёме в никуда.

Добавлено через 1 минуту
Цитата Сообщение от DrobyshevAlex Посмотреть сообщение
MySQL
1
2
3
4
5
6
WHERE `id` IN (
  SELECT `id`
  FROM `personnel_skill`
  WHERE `p`.`id` = `personnel_id`
    AND `skill_id` IN (2, 4)
)
Цитата Сообщение от alpex Посмотреть сообщение
но вот только с IN запрос работал как и старый, поставил id там
Какой `id`? Нет в той таблице никакого `id`. Это виден `id` из какой-то таблицы из внешнего запроса.
0
1178 / 1128 / 94
Регистрация: 31.05.2012
Сообщений: 3,060
10.02.2013, 14:53
Я не смотрел вообще структуру таблиц. Я написал общую суть
Выбираем ид юзеров в подзапросе и выбираем всё для этих юзеров.
0
 Аватар для alpex
603 / 578 / 103
Регистрация: 16.07.2012
Сообщений: 1,762
10.02.2013, 16:54  [ТС]
Цитата Сообщение от Vovan-VE Посмотреть сообщение
Какой `id`? Нет в той таблице никакого `id`. Это виден `id` из какой-то таблицы из внешнего запроса.
ну я конечно же не id там писал а ps.skill_id
0
1178 / 1128 / 94
Регистрация: 31.05.2012
Сообщений: 3,060
10.02.2013, 17:02
Та не скиил_ид а юзер ид. Видимо ка кто так
SQL
1
2
3
4
5
WHERE `p`.`id` IN (
  SELECT `personnel_id`
  FROM `personnel_skill`
  WHERE `skill_id` IN (2, 4)
)
Добавлено через 45 секунд
ну и дистинкт можно добавить в подзапрос)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
10.02.2013, 17:02
Помогаю со студенческими работами здесь

Выборка из базы через join
Доброго времени суток! Проблема такая. Есть 2 таблицы в базе. -- Структура таблицы `site_updates` -- CREATE TABLE IF NOT EXISTS...

Выборка нескольких полей одной таблицы JOIN
SELECT client.name, phone.number FROM info LEFT JOIN client ON client.id = phone.id В таблице client может быть множество...

Выборка с Join
Здравствуйте! Существует две таблицы - с товарами и фильтрами. Фильтры подключены в запрос через join. Первая таблица имеет вид: ...

Выборка с использованием JOIN
Всем привет! Не могли вы помочь бедному студенту с JOIN-ом. &quot;Вывести список названий дисциплин (поле Namesubject из таблицы Subjects)...

Выборка из двух таблиц и Inner Join
выбираю данные из двух таблиц select tehnika.num_teh as Наименование,hist_remont.date_izm from tehnika,hist_remontздесь всё ОК теперь...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru