Форум программистов, компьютерный форум, киберфорум
Наши страницы
PHP: базы данных
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.57/7: Рейтинг темы: голосов - 7, средняя оценка - 4.57
eldalomeo
0 / 0 / 0
Регистрация: 15.02.2014
Сообщений: 5
1

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

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

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

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

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

Делал выборку так:
PHPHTML
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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.02.2014, 19:43
Ответы с готовыми решениями:

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

Как сделать выборку из нескольких таблиц?
всем привет, у меня такая проблемка, на страничке получаю идентификатор...

Запрос на выборку из двух таблиц
столкнулся с такой вот проблемой... существует допустим две таблицы А...

Запрос на выборку из двух таблиц Mysql
Всем доброго времени. Суть вопроса такова : есть 2 таблицы - первая: Куплено...

Средствами php и mysql пытаюсь реализовать выборку из двух таблиц
Добрый день. Есть две таблицы: Первая (tb_ain - таблица с модулями)...

13
KOPOJI
Почетный модератор
Эксперт HTML/CSSЭксперт PHP
16753 / 6644 / 864
Регистрация: 12.06.2012
Сообщений: 19,897
Завершенные тесты: 1
15.02.2014, 20:02 2
PHPHTML
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
eldalomeo
0 / 0 / 0
Регистрация: 15.02.2014
Сообщений: 5
15.02.2014, 21:00  [ТС] 3
Предупреждаю заранее: пишу в первый раз, так что извиняюсь за такое оформление вопроса


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

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 Посмотреть сообщение
PHPHTML
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
DrobyshevAlex
1173 / 1123 / 94
Регистрация: 31.05.2012
Сообщений: 3,059
15.02.2014, 21:47 4
а тчо там не понятного?

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

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

а если учесть, что таблицы у вас одинаковы, то есть по сути по 2 поля, не считая связи, то можно вообще в одной таблице хранить всё
0
eldalomeo
0 / 0 / 0
Регистрация: 15.02.2014
Сообщений: 5
15.02.2014, 22:01  [ТС] 5
Вот как раз только что дошёл до этого.
удивляюсь чего это в IF-е нету условий, только переменная. и понял что это в переменной стоит условие( $tmp != $row['map'])
а так я в процессе обучения PHP. и стараюсь использовать разные варианты решения
как я писал используя LEFT JOIN как раз таки и получается одна таблица, но там категории повторяються получается.
0
zebulun
68 / 68 / 13
Регистрация: 01.09.2011
Сообщений: 379
16.02.2014, 02:17 6
Вообще-то это делается одним запросом
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
DrobyshevAlex
1173 / 1123 / 94
Регистрация: 31.05.2012
Сообщений: 3,059
16.02.2014, 02:34 7
Цитата Сообщение от zebulun Посмотреть сообщение
Вообще-то это делается одним запросом
вообще то во 2 посте и сделано одним запросом

вот только не всегда 1 запрос будет работать оптимальней по ресурсам чем 2 с данной структурой
0
zebulun
68 / 68 / 13
Регистрация: 01.09.2011
Сообщений: 379
16.02.2014, 02:46 8
правильно давайте делать по запросу на категорию так "конечно" оптимальнее
0
DrobyshevAlex
1173 / 1123 / 94
Регистрация: 31.05.2012
Сообщений: 3,059
16.02.2014, 02:48 9
Уважаемый, если Вы не понимаете, о чём речь, не нужно пытаться язвить...
0
KOPOJI
Почетный модератор
Эксперт HTML/CSSЭксперт PHP
16753 / 6644 / 864
Регистрация: 12.06.2012
Сообщений: 19,897
Завершенные тесты: 1
16.02.2014, 10:56 10
zebulun, в данном случае, если объем данных большой, действительно будет оптимальнее использовать два запроса. Первым запросом извлекаются все категории, вторым запросом все товары. Если бы не было вывода заголовка категории, то лучше было бы обойтись одним запросом, здесь лучше несколькими, это я просто плохо подумал..
0
zebulun
68 / 68 / 13
Регистрация: 01.09.2011
Сообщений: 379
16.02.2014, 13:41 11
KOPOJI, А можно более конкретное условие, при котором, в данном случае два запроса лучше, или ссылочку...

Добавлено через 8 минут
KOPOJI, Возможно, вы имели ввиду, если много именно категорий, тогда лучше два запроса?
Если нет, тогда , если нетрудно, конкретизируйте, при каких объемах, в данном случае, лучше два запроса, или ссылочку...
0
KOPOJI
Почетный модератор
Эксперт HTML/CSSЭксперт PHP
16753 / 6644 / 864
Регистрация: 12.06.2012
Сообщений: 19,897
Завершенные тесты: 1
16.02.2014, 13:43 12
Цитата Сообщение от zebulun Посмотреть сообщение
А можно более конкретное условие
Просто представьте пару десятков категорий и в каждой по 1000 товаров (например, часть БД интернет-магазина). Тысячу раз вы будете подхватывать эти категории запросом, тысячи раз будете проверять условиями, какая эта категория. В таком случае лучше Сделать на один запрос больше, но не тянуть лишние данные
0
zebulun
68 / 68 / 13
Регистрация: 01.09.2011
Сообщений: 379
16.02.2014, 16:02 13
Не нашлось подходящей таблицы с 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
DrobyshevAlex
1173 / 1123 / 94
Регистрация: 31.05.2012
Сообщений: 3,059
16.02.2014, 18:36 14
ох... это что за код???
какой нафиг запрос в цикле? где о этом говориться?
вам раз 100 написали что всего 2 запроса.
а вы запросы в цикле шлёте...

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

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

при 1 запросе, будет куча раз дублирование данных, + будет левое соединение, ибо нужно выбрать не толь ко те категории где есть вложения.
трафик между субд и может вырасти в сотни раз из за 1 запроса вместо 2х
выборка с лефт джоин тоже даст доп время.
даже просто формирование ответа от субд и то будет дольше из за ненужных тысяч дублирований строк.
а если это на удалённом хосте, как Вы сами написал? то от трафика ещё время доставки данных возрастёт.
да и в пхп скрипте, если уж на то пошло, память сожрёт гораздо больше, если вернуть дублированный данные.
а представьте что вы выбираете блоги с тегами, 1 запросом, у вас в тысячи раз будет больше памяти расходоваться с 1 запросом, и время тут тоже пострадает, когда на один маленький тег типа ajax будет скопирован весь блог.
0
16.02.2014, 18:36
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.02.2014, 18:36

MySQL + PHP запрос на выборку уникальных строк по последней дате из двух таблиц
Подскажите где ошибка, выдает первую запись по дате, а не последнюю таблицы...

как правильно сделать вывод из бд с двух таблиц)
есть таблицы orders id | name | email и тд. 1 | петя |...

Как сделать выборку из массива?
был запрос mysql извлеченные данные помещены в массив.Как сделать выборку из...


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru