Вопрос по сложным запросам и склейке таблицы

Тема в разделе "Базы Данных", создана пользователем alex_storm, 17 янв 2016.

  1. alex_storm

    alex_storm webdev

    Регистрация:
    11 дек 2012
    Сообщения:
    1.151
    Симпатии:
    667
    Всем привет.

    Вопрос такого плана, как оптимальнее склеивать таблицы?

    Сейчас есть таблица order, которая хранит в себе id customer, product, order_status
    Т.е. 3 типа хранящихся данных.

    Для склейки делаю такой запрос :
    PHP:
    SELECT order_id,order_status.name,product.name,customer.name,customer.city,product.price FROM
    `orderJOIN product ON `order`.product_id=product.product_id
    JOIN customer ON 
    `order`.customer_id=customer.customer_id
    JOIN order_status ON 
    `order`.order_status_id=order_status.order_status_id
    WHERE order_status
    .order_status_id='2' // Тут чисто выборку по статусу заказа делаю
    ORDER BY order_id ASC;
    И получается в итоге таблица http://prntscr.com/9r737s

    Ну мне все нравится, дальше с ней работать можно.

    Единственное что смущает вопрос, а правильно ли я делаю склейку и оптимальна ли такая склейка ? Быть может есть другой более правильный способ.

    Скорость обработки Showing rows 0 - 1 (2 total, Query took 0.0008 sec) [order_id: 1 - 2].
     
  2. $iD

    $iD Команда форума

    Регистрация:
    13 мар 2012
    Сообщения:
    3.580
    Симпатии:
    1.482
    Всё норм) если бы ты не доставал order_status.name, то можно было бы упростить на один джойн.
     
  3. alex_storm

    alex_storm webdev

    Регистрация:
    11 дек 2012
    Сообщения:
    1.151
    Симпатии:
    667
    У меня потом созрел вопрос :Smile:
    Как это дело запихнуть в цикл foreach ?
    Как я понял, все возможно только через while?

    И тут такой момент, если запихивать в ассоциативный массив, там идут 3 колонки с одинаковыми названиями им как то можно дать доп название?
     
  4. $iD

    $iD Команда форума

    Регистрация:
    13 мар 2012
    Сообщения:
    3.580
    Симпатии:
    1.482
    ничего не понял, какое "это" дело? результат работы? если да, то какая разница foreach или while? да хоть for :Smile:
    в sql просто написать:
    Код:
    SELECT
    order_id as SUPERORDERID,
    order_status.name AS ORDERSTATUSNAME
    и т.д.
     
    alex_storm нравится это.
  5. Dotrox

    Dotrox Команда форума

    Регистрация:
    27 ноя 2012
    Сообщения:
    3.198
    Симпатии:
    1.306
    По коду запроса не помешало бы сделать несколько правок:
    - лучше явно указывать тип джоина, чтоб всегда понимать, что к чему и как склеивается (и если кто-то этот код будет потом подерживать, ему тоже было понятно, какая именно склейка задумывалась автором)
    - лучше использовать алиасы для имён таблиц, чтоб сократить код запроса и сделать его более читаемым:
    PHP:
    SELECT o.order_id FROM `ordero
    - для лучшей читаемости сопоставление id по ON лучше обернуть в круглые скобки:
    PHP:
    ON (o.product_id p.product_id)
    А там действительно должно на один заказ получаться несколько разных имён?
     
    alex_storm нравится это.
  6. $iD

    $iD Команда форума

    Регистрация:
    13 мар 2012
    Сообщения:
    3.580
    Симпатии:
    1.482
    Это всё конечно +, но конкретно на перфоманс это не влияет.

    Для удобочитаемости - так нужно делать 100%.
     
  7. alex_storm

    alex_storm webdev

    Регистрация:
    11 дек 2012
    Сообщения:
    1.151
    Симпатии:
    667
    Это имя: Товара, Покупателя
     
  8. alex_storm

    alex_storm webdev

    Регистрация:
    11 дек 2012
    Сообщения:
    1.151
    Симпатии:
    667
    Я просто не могу понять, как его вывести.
    Когда делаю mysql_fetch_assoc, то по какой то причине выводится только один результат.

    Когда делаю for, падает браузер) хз, мб из-за того, что делаю при каждой итерации запрос в бд.
    Делал проверку, если вывести $rows то показывает число =4. Следовательно цикл не может делать больше итераций, чем 4. Но он херячит их без остановки.
    PHP:
    <?php
        $query 
    'SELECT * FROM product';
        
    $result mysql_query($query);

        if(!
    $result) die ('Запрос не прошел' mysql_error());
        
    $rows mysql_fetch_row($result);
        for(
    $j=0;$j<$rows;$j++){
            
    $row mysql_fetch_row($result);
        
    ?>
            <tr>
                <td><?php echo $row[0]; ?></td>
                <td><?php echo $row[1]; ?></td>
                <td><?php echo $row[2]; ?></td>
                <td><?php echo $row[3]; ?></td>
                <td><?php echo $row[4]; ?></td>
                <td><a href="#">удалить</a></td>
            </tr>
        <?php ?>
    И тут сразу другой вопрос :Smile:

    Вот вверху идет цикл, я его как то запущу, но я хотел сделать 1 запрос на 1 таблицу, чтобы не заморачиваться. И внизу вывести дополнительные значения.
    Типа
    PHP:
    <select name="category_id">
                <?php for($j=0;$j<$rows;$j++){ ?>
                    <option value="<?php echo $row[5]; ?>"><?php echo $row[6]; ?></option>
                <?php ?>
            </select>
    Можно ли так делать?

    На практике показало, что по идеи нет, т.к. оно считает кол-во строк и всегда будет выводить последний элемент строки.
     
  9. $iD

    $iD Команда форума

    Регистрация:
    13 мар 2012
    Сообщения:
    3.580
    Симпатии:
    1.482
    я хз, но по коду ты делаешь не так :Smile:

    либо так (только вместо $row[0], $row[1].... у тебя будет $row['name'], $row['type']):

    PHP:
    <?php
    $query 
    'SELECT * FROM product';
    $result mysql_query($query);

    if (!
    $result) die ('Запрос не прошел' mysql_error());

    while (
    $row mysql_fetch_assoc($result)) { ?>
        <tr>
            <td><?php echo $row[0]; ?></td>
            <td><?php echo $row[1]; ?></td>
            <td><?php echo $row[2]; ?></td>
            <td><?php echo $row[3]; ?></td>
            <td><?php echo $row[4]; ?></td>
            <td><a href="#">удалить</a></td>
        </tr>
    <?php ?>
    Либо так (если хочешь mysql_fetch_row):
    PHP:
    <?php
    $query 
    'SELECT * FROM product';
    $result mysql_query($query);

    if (!
    $result) die ('Запрос не прошел' mysql_error());

    while (
    $row mysql_fetch_row($result)) { ?>
        <tr>
            <td><?php echo $row[0]; ?></td>
            <td><?php echo $row[1]; ?></td>
            <td><?php echo $row[2]; ?></td>
            <td><?php echo $row[3]; ?></td>
            <td><?php echo $row[4]; ?></td>
            <td><a href="#">удалить</a></td>
        </tr>
    <?php ?>
    Я слегка наврал, про for и foreach, т.к. mysql_fetch_* возвращает строку и сдвигает внутренний указатель на сл. элемент. Так что лопать через while.
    Можно. Например можно собрать результат в массив:
    PHP:
    <?php
    $query 
    'SELECT * FROM product';
    $response mysql_query($query);

    if (!$
    $response) die ('Запрос не прошел' mysql_error());

    $results = [];
    while (
    $row mysql_fetch_assoc($response)) { ?>
      $results[] = $row;
    <?php ?>
    а потом что хочешь то и делай. хочешь первые 4 выводи в одном месте, а остальное в другом.
     
    alex_storm нравится это.