IMHO.WS

IMHO.WS (https://www.imho.ws/index.php)
-   Веб-программирование (https://www.imho.ws/forumdisplay.php?f=29)
-   -   Сортировка массива В PHP+MySQL (https://www.imho.ws/showthread.php?t=87700)

Hatifnatt 16.06.2005 19:40

Сортировка массива В PHP+MySQL
 
Люди нужна ваша помощь!!!
Надо отсортировать такой вот массив (берется он из MySQL-я)

Код:

id |  thing  |  company  |
---------------------------
 01 | thing01 | company01 |
 02 | thing02 | company01 |
 03 | thing03 | company01 |
 04 | thing04 | company02 |
 05 | thing05 | company02 |
 06 | thing06 | company02 |
 07 | thing07 | company01 |
 08 | thing08 | company01 |
 09 | thing09 | company03 |
 10 | thing10 | company03 |
..............

Надо произвести вот такую сортировку:
Сначала должны идти нужные компании, например company03 и вся ее продукция, потом должна идти следующая нужная компания например company01 и вся ее продукция и т.д. последовательность компаний может браться из еще одной таблицы или быть прописана прямо в коде, это не принципиально. Сортировка thing-ов не важна, ну точнее не очень важна, но если она будет, чтож - хорошо ;) Да, thing-и должны сортироваться внутри своей компании, а не во всей таблице.

Соответственно можно загнать всю базу в PHP массив и сортировать его, а можно попытаться выполнить сортировку с помощью запросов MySQL, а можно и совместить два эти метода. Можно внести в таблицу еще один параметр, что-то типа индекса положения компании, например при 1 компания на 1-ом месте, при 2 на втором и т.д., а компании без этого индекса идут после индексированных в алфавитном порядке.

Ваши советы, рекомендации (желательно с примером кода :) ), а то у меня есть куча идей, да не знаю как же все-таки все это лучше сделать.

Всем соответственно заранее огромное спасибо. :)

Naked 16.06.2005 21:24

Ну присваивать компаниям еще дополнительные номера - это удобно, но вроде не очень приветствуется примерными программистами :p Хотя это не плохой вариант. Но я бы прямо в PHP выполнил несколько запросов:
SELECT from <table> where company=company01
Select from <table> where company=company02 и т.д. А если company01 и company02 будут значениями какой-нибудь переменной вроде: $company="company01"; $sql="SELECT from <table> where company=" то в процессе программы придется менять только $company а запрос будет выглядеть как mysql_query($sql.$company) (точно функцию mysql_query не помню, может не так пишется...). :rolleyes:

Неизвестный 17.06.2005 01:45

На самом деле кривые таблицы.
Лучше сделать так:
1. Таблица <table_1> содержит названия компаний, ее контакты и так далее. В этой таблице каждой компании присвоится уникальный айди.
2. Таблица <table_2> содержит информацию по производству компаний, где в роли определителя компании служит уникальный айди с первой базы.
Теперь SQL-запрос:
Код:

$sql = mysql_query("SELECT id, name FROM <table_1>");
while($row = mysql_fetch_array($sql))
{
  $id = $row['id'];
  $name = $row['name'];
  // Вывод названия компании
  print "Компания ".$name." производит следующее:";
  // Делаем запрос ко второй базе, по айдишнику компании, что бы получить ее продукцию
  $sql2 = mysql_query("SELECT production, ..., ... FROM <table_2> WHERE company_id='$id'");
  if(mysql_num_rows($sql2) < 1) print "Ничего не производит.";
  while($myrow = mysql_fetch_array($sql2))
  {
    // Делаем вывод прозводства
    print $myrow['production'].", ".$myrow['...'];
  }
}


EvroStandart 17.06.2005 11:01

Разбить на две таблицы - это правильно.
А ещё можно всё в один большой запрос запихать через JOIN

Неизвестный 17.06.2005 13:58

EvroStandart
Можно конечно. Я привел простейший пример.

Вот как выглядит все одним запросом.
Код:

SELECT t1.id, t1.name, t2.production, t2.[...], t2.[...] FROM <table_1> t1, <table_2> t2 WHERE t2.company_id=t1.id
Вроде верно.

Hatifnatt 17.06.2005 17:10

Цитата:

Неизвестный:
На самом деле кривые таблицы.
Лучше сделать так:
1. Таблица <table_1> содержит названия компаний, ее контакты и так далее. В этой таблице каждой компании присвоится уникальный айди.
2. Таблица <table_2> содержит информацию по производству компаний, где в роли определителя компании служит уникальный айди с первой базы.
Не вижу особого смысла вводить айди для каждой компании, ведь впринципе имя компании уникально (в любом случае у меня в базе) и можно не заморачиваться с дополнительными id-шниками. Где я неправ?
Мне незачем разводить несколько таблиц, айдишник конечно весит меньше чем имя компании (информацию по компаниям можно сложить в отдельную таблицу, но пока в этом нет необходимости, мне нужно только имя компании), но у меня не такая уж и большая база чтоб заморачиваться по этому поводу. Вторая таблица мне нужна для того, чтоб там хранить очередность (по именам компаний) по которой компании должны идти при выводе.
Я склоняюсь к варианту The_naked выбирать из базы товары нужного производителя и загонять их в массив PHP в нужном порядке, а потом выводить. Мне можно на самом деле написать скрипт который будет сортировать не результат (выводимый юзеру) из перемешанной базы при каждом запросе юзера, а будет сортировать САМУ базу ОДИН раз (из админки или чего-то типа того), а потом выводится будет просто все подряд. Нагрузка на сервер меньше - быстродействие больше. Или что-то в моих мыслЯх неверно? Сортировка на лету по запросу пользователя мне пока не нужна.

sht62 22.06.2005 03:29

To:Hatifnatt

Наиболее очевидно сделать следующее:
1) Заводим таблицу Т1 с именами компаний в нужном порядке.
2) Получаем список ВСЕХ компаний из основной таблицы в временную таблицу Т2.
3) Последовательно выбираем из базы продукты для имени компании из таблицы Т1. После выбора всех продуктов, удаляем имя этой компании из таблицы Т2.
4) После окончания обработки всех записей имен компаний из таблицы Т1 выбираем из базы продукты по ОСТАВШИМСЯ именам компаний из таблицы Т2.

Пример кода не даю ибо не силён в PHP :cool: (думаю что это должно быть просто, так как решение простое).
Возможно найдётся человек, который составит более элегантный алгоритм или предложит другое решение.
Может быть возможно избавиться от пункта 2 и тем самым уменьшить количество обращений к базе :idontnow: .

Hatifnatt 23.06.2005 18:46

Вот решение:
Код:

<?php
//Подключаемся к базе, выбираем все записи сортируем по имени компании,
//а потом по названию продукта
mysql_select_db(DBName);
$new=mysql_query("select * from table order by company,title");
//Всего строк
$rows_owerall=mysql_num_rows($new);
//Создаем переменные
$company= array();
$sequence=array();

echo "Всего строк: ".$rows_owerall."<br>";

$comp_name = mysql_query("select * from Games group by company order by company");
echo "<br>Comp name: ".$comp_name." end <br>";
$comp_count = mysql_num_rows($comp_name);

// Cocтавляем список ВСЕХ компаний

while($single_row=mysql_fetch_assoc($comp_name))
{
  $company[]=$single_row[company];
}

// Отобразим список полученных компаний

for($j=0; $j<count($company); $j++ )
{
  echo "Company ".$company[$j]."<br>";
}

$comp_sequence=mysql_query("select company from comp_order");
$sql_start="SELECT * FROM table WHERE company LIKE '";
$sql_end="' ORDER BY title";

// Извлекаем записи по УКАЗАННОЙ компани
echo "<br>Comp_sequence: ".$comp_sequence." end<br>";

while($single_row = mysql_fetch_assoc($comp_sequence))
{
 $company_name=$single_row[company];
 echo "<br>Запрос: ".$sql_start.$company_name.$sql_end;
 $product_seq = mysql_query($sql_start.$company_name.$sql_end);
 while($comp_row=mysql_fetch_assoc($product_seq))
 {
  $sequence[]=array(
                      "id"=>$comp_row[id],
                      "title"=>$comp_row[title]
                      "company"=>$comp_row[company]);
 }

// Удаляем из списка ВСЕХ компаний обработаные компании

 for($j=0; $j<count($company); $j++)
 {
    if($company[$j]==="") continue;
    if($company[$j]==="$company_name")
    {
      $company[$j]="";
      break;
    }
 }
}

// Добавляем продукты оставшихся компаний

for($j=0; $j<count($company); $j++)
{
  if($company[$j]==="") continue;
  $company_name=$company[$j];
  echo "<br>Запрос: ".$sql_start.$company_name.$sql_end;
  $product_seq = mysql_query($sql_start.$company_name.$sql_end);
  while($comp_row=mysql_fetch_assoc($product_seq))
  {
    $sequence[]=array(
    "id"=>$comp_row[id],
    "title"=>$comp_row[title],
    "company"=>$comp_row[company]);
  }
}


echo "<br>Проверяем массив <br>";

for ($j=0; $j<count($sequence); $j++)
{
echo $j." ".$sequence[$j][id].
          " ".$sequence[$j][title].
          " ".$sequence[$j][company]."<br>";
}
?>

может кто подскажет более оптимальный вариат.

Saruman 23.06.2005 23:27

Хм, а зачем вы такие хитрые-то?

Если список всех компаний заранее известен и не слишком велик, то можно без проблем использовать ORDER BY FIELD:
Код:

SELECT * FROM tablename ORDER BY FIELD(company, 'company3', 'company1', ....)
Если список неизвестен или слишком велик, то делать ORDER BY FIND_IN_SET:
Код:

SELECT * FROM tablename ORDER BY FIND_IN_SET(company, 'company1,company3') DESC

Hatifnatt 24.06.2005 12:52

Saruman
Спасибо, пожалуй переделаю так как ты советуешь. Намного более простой и быстрый вариант. :yees:


Часовой пояс GMT +4, время: 19:13.

Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.