Форум программистов, компьютерный форум, киберфорум
PHP: базы данных
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.91/11: Рейтинг темы: голосов - 11, средняя оценка - 4.91
0 / 0 / 0
Регистрация: 15.02.2014
Сообщений: 5

Как лучше сделать выборку из двух таблиц?

15.02.2014, 19:43. Показов 2349. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
У меня две таблицы:

IDПредметы
1Фрукты
2Обощи
3Мясо
и
IDНаименованиеID_Предмета
1Яблоки1
2Груши1
3Помидоры2
4Огурцы2
5Баранина3
6Свинина3
7Говядина3

Надо сделать выборку:
Фрукты
  • Яблоки
  • Груши
Обощи
  • Помидоры
  • Огурцы
Мясо
  • Баранина
  • Свинина
  • Говядина

Делал выборку так:
PHP/HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
        $records = array();
        $sel = $mysqli->query('SELECT * FROM maps');
        while( $row = $sel->fetch_assoc() ){
            $records[] = $row;
        }
 foreach ($records as $row): ?>
    <h4><p><?=$row['map']?></p></h4>
    <ul>
        <?php 
        $id_map2 = $row['id'];
        $loc = array();
        $sel2 = $mysqli->query("SELECT * FROM location WHERE id_map = ".$id_map2);
        while( $row2 = $sel2->fetch_assoc() ){
            $loc[] = $row2;
        }
        foreach ($loc as $row2): ?>
        <li><?=$row2['loc_name']?></li>
        
   
        <?php endforeach ?> 
    </ul>
    <?php endforeach ?>
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
15.02.2014, 19:43
Ответы с готовыми решениями:

Как сделать выборку из двух таблиц в бд
Есть 2 таблицы в одной все пользователи, а вторая с именем и доступом к контенту Как сделать запрос который выбирает пользователей у...

Как сделать выборку для двух таблиц?
У меня есть такая проблема! В общем есть две таблицы cat1 (id, name) и cat2 (id, name) и Надо выбрать с двух таблиц данные (сравнение будет...

Как сделать linq выборку из двух таблиц в одну GridView?
Есть две таблицы которые имеют одинакоывый первичный ключ. Как мне сделать выборку из них средствами linq и занести получненые даные в...

13
Почетный модератор
Эксперт HTML/CSSЭксперт PHP
 Аватар для KOPOJI
16844 / 6724 / 880
Регистрация: 12.06.2012
Сообщений: 19,967
15.02.2014, 20:02
PHP/HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
$sel = $mysqli->query('SELECT * FROM `location` `l` LEFT JOIN `maps` `m` ON `l`.`id_map` = `m`.`id`');
$tmp = NULL;
while( $row = $sel->fetch_assoc() ) : ?>
    <?php $is_new_cat = $tmp != $row['map']) ?>
    <?php if($is_new_cat) : ?>
        <?php $tmp = $row['map']; ?>
        <h4><p><?=$row['map']?></p></h4>
        <ul>
    <?php endif; ?>
    <li><?=$row2['loc_name']?></li>
    <?php if($is_new_cat) : ?>
        </ul>
    <?php endif; ?>
<?php endwhile; ?>
Как-то так, по идее, можно.. Только логику вывода закрывающего тега </ul> чуть подправить, мне, к сожалению, сейчас некогда.
1
0 / 0 / 0
Регистрация: 15.02.2014
Сообщений: 5
15.02.2014, 21:00  [ТС]
Предупреждаю заранее: пишу в первый раз, так что извиняюсь за такое оформление вопроса


У меня две таблицы:

IDПредметы
1Фрукты
2Обощи
3Мясо
и
IDНаименованиеID_Предмета
1Яблоки1
2Груши1
3Помидоры2
4Огурцы2
5Баранина3
6Свинина3
7Говядина3

Надо сделать выборку:
Фрукты
  • Яблоки
  • Груши
Обощи
  • Помидоры
  • Огурцы
Мясо
  • Баранина
  • Свинина
  • Говядина

Делал выборку так:
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
        $records = array();
        $sel = $mysqli->query('SELECT * FROM Предмет');
        while( $row = $sel->fetch_assoc() ){
            $records[] = $row;
        }
        foreach ($records as $row): ?>
    <b><?=$row['Предмет']?></b>
    <ul>
        <?php 
        $id_item = $row['id'];
        $loc = array();
        $sel2 = $mysqli->query("SELECT * FROM Наименование WHERE ID_Предмета = ".$id_item);
        while( $row2 = $sel2->fetch_assoc() ){
            $loc[] = $row2;
        }
        foreach ($loc as $row2): ?>
        <li><?=$row2['Наименование']?></li>
        
   
        <?php endforeach ?> 
    </ul>
    <?php endforeach ?>
Всё работает хорошо. Но не слишком ли это нагружает базу?
Слишком много раз обращается к базе
Решил сделать выборку с LEFT JOIN:

SQL
1
2
3
SELECT n.ID_Предмета, i.ID, i.Предметы, n.Наименоваение
FROM Наименования AS n
LEFT JOIN Предметы AS i ON i.ID_Предмета = n.id
Получается:
ID_ПредметаIDПредметыНаименования
11ФруктыЯблоки
11ФруктыГруши
22ОвощиПомидоры
22ОвощиОгурцы
33МясоБаранина
33МясоСвинина
33МясоГовядина

как из этого безобразия сделать списки? Ведь {Предметы}(Фрукты,Овощи и Мясо) повторяться будут. А м не надо чтобы один раз они вышли

Как лучше? Или подскажите другой вариант

Добавлено через 57 секунд
Извиняюсь в начале нечаянно отправил не дописав

Добавлено через 20 минут
Цитата Сообщение от KOPOJI Посмотреть сообщение
PHP/HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
$sel = $mysqli->query('SELECT * FROM `location` `l` LEFT JOIN `maps` `m` ON `l`.`id_map` = `m`.`id`');
$tmp = NULL;
while( $row = $sel->fetch_assoc() ) : ?>
    <?php $is_new_cat = $tmp != $row['map']) ?>
    <?php if($is_new_cat) : ?>
        <?php $tmp = $row['map']; ?>
        <h4><p><?=$row['map']?></p></h4>
        <ul>
    <?php endif; ?>
    <li><?=$row2['loc_name']?></li>
    <?php if($is_new_cat) : ?>
        </ul>
    <?php endif; ?>
<?php endwhile; ?>
Как-то так, по идее, можно.. Только логику вывода закрывающего тега </ul> чуть подправить, мне, к сожалению, сейчас некогда.
Спасибо получилось. буду разбирать данный вариант. там и впрямь надо со списками поработать, а то выход не ровный получается.

Добавлено через 30 минут
Цитата Сообщение от KOPOJI Посмотреть сообщение
[PHPHTML]<?php
...
<?php $is_new_cat = $tmp != $row['map']) ?>
...
стыдно признаться, но не могу понять логику этого участка кода
кто может объяснить как тут действует присвоение?
0
1178 / 1128 / 94
Регистрация: 31.05.2012
Сообщений: 3,060
15.02.2014, 21:47
а тчо там не понятного?

$is_new_cat присваивается значение выражения $tmp != $row['map']

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

а если учесть, что таблицы у вас одинаковы, то есть по сути по 2 поля, не считая связи, то можно вообще в одной таблице хранить всё
0
0 / 0 / 0
Регистрация: 15.02.2014
Сообщений: 5
15.02.2014, 22:01  [ТС]
Вот как раз только что дошёл до этого.
удивляюсь чего это в IF-е нету условий, только переменная. и понял что это в переменной стоит условие( $tmp != $row['map'])
а так я в процессе обучения PHP. и стараюсь использовать разные варианты решения
как я писал используя LEFT JOIN как раз таки и получается одна таблица, но там категории повторяються получается.
0
71 / 71 / 13
Регистрация: 01.09.2011
Сообщений: 379
16.02.2014, 02:17
Вообще-то это делается одним запросом
SQL
1
2
SELECT f.name AS food, p.name AS product FROM `foods` AS f
JOIN products AS p ON f.id = p.food_id
0
1178 / 1128 / 94
Регистрация: 31.05.2012
Сообщений: 3,060
16.02.2014, 02:34
Цитата Сообщение от zebulun Посмотреть сообщение
Вообще-то это делается одним запросом
вообще то во 2 посте и сделано одним запросом

вот только не всегда 1 запрос будет работать оптимальней по ресурсам чем 2 с данной структурой
0
71 / 71 / 13
Регистрация: 01.09.2011
Сообщений: 379
16.02.2014, 02:46
правильно давайте делать по запросу на категорию так "конечно" оптимальнее
0
1178 / 1128 / 94
Регистрация: 31.05.2012
Сообщений: 3,060
16.02.2014, 02:48
Уважаемый, если Вы не понимаете, о чём речь, не нужно пытаться язвить...
0
Почетный модератор
Эксперт HTML/CSSЭксперт PHP
 Аватар для KOPOJI
16844 / 6724 / 880
Регистрация: 12.06.2012
Сообщений: 19,967
16.02.2014, 10:56
zebulun, в данном случае, если объем данных большой, действительно будет оптимальнее использовать два запроса. Первым запросом извлекаются все категории, вторым запросом все товары. Если бы не было вывода заголовка категории, то лучше было бы обойтись одним запросом, здесь лучше несколькими, это я просто плохо подумал..
0
71 / 71 / 13
Регистрация: 01.09.2011
Сообщений: 379
16.02.2014, 13:41
KOPOJI, А можно более конкретное условие, при котором, в данном случае два запроса лучше, или ссылочку...

Добавлено через 8 минут
KOPOJI, Возможно, вы имели ввиду, если много именно категорий, тогда лучше два запроса?
Если нет, тогда , если нетрудно, конкретизируйте, при каких объемах, в данном случае, лучше два запроса, или ссылочку...
0
Почетный модератор
Эксперт HTML/CSSЭксперт PHP
 Аватар для KOPOJI
16844 / 6724 / 880
Регистрация: 12.06.2012
Сообщений: 19,967
16.02.2014, 13:43
Цитата Сообщение от zebulun Посмотреть сообщение
А можно более конкретное условие
Просто представьте пару десятков категорий и в каждой по 1000 товаров (например, часть БД интернет-магазина). Тысячу раз вы будете подхватывать эти категории запросом, тысячи раз будете проверять условиями, какая эта категория. В таком случае лучше Сделать на один запрос больше, но не тянуть лишние данные
0
71 / 71 / 13
Регистрация: 01.09.2011
Сообщений: 379
16.02.2014, 16:02
Не нашлось подходящей таблицы с 1000 записей на категорию, но вот нашлась такая
BEGIN: 1392551740.2562
END:1392551740.2731
END - BEGIN: 0.016964912414551
MY RESULT WITH 168 CATEGORIES AND 1990 ARTICLES = 0.016964912414551


BEGIN: 1392551740.2731
END2:1392551740.3101
END2 - BEGIN2: 0.036981105804443
YOUR RESULT WITH 168 CATEGORIES AND 1990 ARTICLES = 0.036981105804443
PHP
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
$begin = microtime(1);
echo 'BEGIN: ' . $begin . '<br>';
$query = $conn->query('select c.name as category, c.id as category_id, a.title as article from categories as c
    left join articles as a on c.id = a.category_id ');
 
$articles = array();
while ($row = $query->fetch_assoc()) {
    //echo $row['category_id']. '<br>';
    if (!empty($row['article']))$articles[$row['category_id']][] = $row['article'];
    else $articles[$row['category_id']] = array();
}
 
 
$cCategories = 0;
$cArticles = 0;
foreach ($articles as $category => $categoryArticles) {
    //echo $category . '--><br>' ;
    $cCategories++;
    foreach ($categoryArticles as $article) {
        //echo '&nbsp&nbsp&nbsp&nbsp' . $article . '<br>';
        $cArticles++;
    }
}
$end = microtime(1);
echo 'END:' . $end . '<br>';
$result = $end - $begin;
echo 'END - BEGIN: '. $result .'<br>';
echo '<b> MY RESULT WITH ' . $cCategories . ' CATEGORIES AND ' .$cArticles. ' ARTICLES =
<span style="color:red;">' . $result .'</span></b><br><br><br>';
 
/***
 *
 *   MULTIPLY QUERIES
 */
 
$begin2 = microtime(1);
echo 'BEGIN: ' . $begin2 . '<br>';
$query2 = $conn->query('select name , id from categories');
$stmt = $conn->prepare('SELECT title as name from articles where category_id = ?');
 
$cCategories = 0;
$cArticles = 0;
while ($rowC = $query2->fetch_assoc()) {
    //echo $rowC['name']. '--><br>' ;
    $cCategories ++;
    $stmt->bind_param('i', $rowC['id']);
    $stmt->execute();
    $res = $stmt->get_result();
    while ($rowA = $res->fetch_assoc()) {
        //echo '&nbsp&nbsp&nbsp&nbsp' . $rowA['name'] . '<br>';
        $cArticles++;
    }
}
 
$end2 = microtime(1);
echo 'END2:' . $end2 . '<br>';
$result2 = $end2 - $begin2;
echo 'END2 - BEGIN2: '. $result2 .'<br>';
echo '<b> YOUR RESULT WITH ' . $cCategories . ' CATEGORIES AND ' .$cArticles. ' ARTICLES =
<span style="color:red;">' . $result2 .'</span></b>';
База на локалхосте, а если база будет на другом хосте вторые цифры изменяться значительно.
0
1178 / 1128 / 94
Регистрация: 31.05.2012
Сообщений: 3,060
16.02.2014, 18:36
ох... это что за код???
какой нафиг запрос в цикле? где о этом говориться?
вам раз 100 написали что всего 2 запроса.
а вы запросы в цикле шлёте...

нормальный код, при такой таблице как у ТС, будет отличатся на на 1-5%, а у вас на 300%.
а если не будет индексов, так код с 1 запросом изначально проиграет.

да и зачем вы засекаете время всего скрипта? с пхп кодом?
бд нужно разгружать чаще сем пхп.
простой пример, сайт с 30к уников в день, нагрузка на проц от сайта 4-5% в пик
нагрузка на бд до 100%.
а вы тут замеряете пхп код...

при 1 запросе, будет куча раз дублирование данных, + будет левое соединение, ибо нужно выбрать не толь ко те категории где есть вложения.
трафик между субд и может вырасти в сотни раз из за 1 запроса вместо 2х
выборка с лефт джоин тоже даст доп время.
даже просто формирование ответа от субд и то будет дольше из за ненужных тысяч дублирований строк.
а если это на удалённом хосте, как Вы сами написал? то от трафика ещё время доставки данных возрастёт.
да и в пхп скрипте, если уж на то пошло, память сожрёт гораздо больше, если вернуть дублированный данные.
а представьте что вы выбираете блоги с тегами, 1 запросом, у вас в тысячи раз будет больше памяти расходоваться с 1 запросом, и время тут тоже пострадает, когда на один маленький тег типа ajax будет скопирован весь блог.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
16.02.2014, 18:36
Помогаю со студенческими работами здесь

Как сделать выборку из двух таблиц БД Access и отобразить на форме
Друзья, помогите мне с небольшой проблемкой. -- В проекте подключил БД (Базу данных Access.mdb) В проекте у меня 2 формы! (MainForm,...

Сделать выборку из двух таблиц
: В реляционной БД имеются две таблицы: • Clients (client_id, client_name) - клиенты • Orders (order_id, client_id, order_sum,...

Сделать выборку из двух таблиц
Всем доброго вечера! Прошу помощи на составление sql-запроса. Задача: есть две таблицы - users и orders. Надо сделать выборку...

Как сделать выборку из двух таблиц, где отличаются по типу один из столбцов. Выдать надо все данные
Форумчане, доброго всем вечера! Сталкнулась с такой проблемой. Есть две таблицы, они соединены по одному столбцу как по первичному ключу....

Сделать выборку из двух таблиц по условию
Есть 2 таблицы с данными. Таблица_1 День_недели | Скидка 1 ...


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru