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

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

15.02.2014, 19:43. Показов 2378. Ответов 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
Ответ Создать тему
Новые блоги и статьи
Вывод данных через динамический список в справочнике
Maks 01.04.2026
Реализация из решения ниже выполнена на примере нетипового справочника "Спецтехника" разработанного в конфигурации КА2. Задача: вывести данные из ТЧ нетипового документа. . .
Функция заполнения текстового поля в реквизите формы документа
Maks 01.04.2026
Алгоритм из решения ниже реализован на нетиповом документе "ВыдачаОборудованияНаСпецтехнику" разработанного в конфигурации КА2, в дополнении к предыдущему решению. На форме документа создается. . .
К слову об оптимизации
kumehtar 01.04.2026
Вспоминаю начало 2000-х, университет, когда я писал на Delphi. Тогда среди программистов на форумах активно обсуждали аккуратную работу с памятью: нужно было следить за переменными, вовремя. . .
Идея фильтра интернета (сервер = слой+фильтр).
Hrethgir 31.03.2026
Суть идеи заключается в том, чтобы запустить свой сервер, о чём я если честно мечтал давно и давно приобрёл книгу как это сделать. Но не было причин его запускать. Очумелые учёные напечатали на. . .
Модель здравосоХранения 6. ESG-повестка и устойчивое развитие; углублённый анализ кадрового бренда
anaschu 31.03.2026
В прикрепленном документе раздумья о том, как можно поменять модель в будущем
10 пpимет, которые всегда сбываются
Maks 31.03.2026
1. Чтобы, наконец, пришла маршрутка, надо закурить. Если сигарета последняя, маршрутка придет еще до второй затяжки даже вопреки расписанию. 2. Нaдоели зима и снег? Не надо переезжать. Достаточно. . .
Перемещение выделенных строк ТЧ из одного документа в другой
Maks 31.03.2026
Реализация из решения ниже выполнена на примере нетипового документа "ВыдачаОборудованияНаСпецтехнику" с единственной табличной частью "ОборудованиеИКомплектующие" разработанного в конфигурации КА2. . . .
Functional First Web Framework Suave
DevAlt 30.03.2026
Sauve. IO Апнулись до NET10. Из зависимостей один пакет, работает одинаково хорошо как в режиме проекта так и в интерактивном режиме. из сложностей - чисто функциональный подход. Решил. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru