2016-12-21 5 views
2

У меня возникли проблемы с попыткой получить данные из моей базы данных и показать их правильно. У меня есть макет, где у меня есть два «списка», где я могу добавлять строки в каждый список. Я могу добавить несколько строк в каждый список.Список записей, сгруппированных по категориям

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

В настоящее время, он показал, как это:

LIST #1 
-- row inside list #1 -- 
-- row inside list #1 -- 

    LIST #2 
-- row inside list #2 -- 

В настоящее время, это отображение, как это:

LIST #1 
-- row inside list #1 -- 
    LIST #2 
-- row inside list #2 -- 
    LIST #1 
-- row inside list #1 -- 

Ниже визуально:

Problem visualized

Это мой выбор в PHP:

$driving=$dbh->prepare("SELECT 
    driving_lists.id, 
    driving_lists.list_id, 
    driving_lists.date, 
    driving_lists.list_name, 
    driving_list_shipments.* 
FROM 
    driving_lists 
     LEFT JOIN driving_list_shipments ON driving_lists.list_id = driving_list_shipments.list_id 

    "); 
    $driving->execute(); 

И выход сценария:

foreach($driving as $row){ 
       echo "<pre>"; 
       echo $row["list_name"]; 
       echo "<br />"; 
       echo $row["reference"]; 
       echo "</pre>"; 
     } 

Что я делаю неправильно?

ответ

7

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

PDO can group results into the nested arrays, основанный на первом выбранном поле. Так что вам нужно перечислить список своего идентификатор в качестве первого поля в списке полого, а затем получить ваши строки, используя fetchAll() с вышеупомянутым режимом выборки:

$sql = "SELECT dl.list_id, dl.id, dl.date, dl.list_name, dls.* 
    FROM driving_lists dl LEFT JOIN 
    driving_list_shipments dls 
ON dl.list_id = dls.list_id 
ORDER BY dl.list_id"; 

$driving = $dbh->query($sql)->fetchAll(PDO::FETCH_GROUP); 

и теперь вы получите аккуратный вложенный массив, где ваши строки сгруппированы по список id!

Для того, чтобы вывести его аккуратно нужно использовать два вложенных операторов Foreach

foreach ($driving as $list_id => $list_data) 
{ 
    echo $list_data[0]['list_name']."<br />\n"; 
    foreach ($list_data as $row) 
    { 
     echo "whatever"; 
    } 
} 
+0

Это очень мило! Работает как шарм.Однако, просто вопрос относительно двойного вложенного заявления foreach - как это влияет на производительность? – oliverbj

+1

Это не влияет на производительность вообще –

+0

А, это потому, что моя логика подсказывала мне, что это эквивалент наличия вложенных операторов SQL. Большое спасибо, это работает отлично! – oliverbj

0

Если вы запустите SQL-запрос и хотите получить результат в определенном порядке, то ALWAYS содержит предложение order by.

В вашем случае, вы, кажется, хотят:

SELECT dl.id, dl.list_id, dl.date, dl.list_name, 
     dls.* 
FROM driving_lists dl LEFT JOIN 
    driving_list_shipments dls 
    ON dl.list_id = dls.list_id 
ORDER BY dl.list_id; 

Я предполагаю, что list_id является то, что вы имеете в виду list_id.

Следует отметить, что у вас есть list_id, появляющийся дважды в SELECT, так как он находится в обеих таблицах. Вероятно, вы должны явно указывать столбцы, которые вы хотите, из обеих таблиц, и избегать избыточных столбцов.

+0

Такого рода список правильно, однако это не объединение всех строк внутри списка. Теперь он отображает список LIST для каждой строки внутри этого списка. Я хочу объединить строки списка внутри каждого списка. – oliverbj

+0

Вы должны сделать это «слияние» на уровне приложения. –

+0

Я не совсем уверен, где вы видите list_id дважды в списке? Я вижу только «list_id» и «id» – oliverbj