SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 23.09.2013 11:15:58

Targarien
Участник
Зарегистрирован: 23.09.2013
Сообщений: 7

Выборка из таблицы по критерию совпадения из двух других таблиц

Прошу помочь составить запрос для такого случая.
Есть три таблицы - список провайдеров (providers), список услуг (services), список городов (cities); все таблицы созданы одинаково с PRIMARY KEY id.
+----+-----------+
| id   |   name   |
+----+-----------+
Нужно выбрать всех провайдеров, предоставляющих конкретную услугу в данном городе. Вид услуги и город выбираются в HTML-форме и передаются PHP-скрипту.
Я создал и таблицу связки (reference), в которую заносятся только идентификаторы провайдеров и  идентификаторы соответствующих им сервисов и городов. Мой SQL-запрос выглядит так:

SELECT p.image, p.name, p.descr, p.addr, p.phones, p.comment, s.name, c.name  
FROM providers AS p, reference AS r, services AS s, cities AS c
WHERE p.id = r.prov_id
AND r.serv_id = (SELECT services.id FROM services WHERE services.name = 'service')
AND r.city_id = (SELECT cities.id FROM cities WHERE cities.name = 'city');

но он не работает, выдает ошибку:
"Не найдена ни одна строка!"

Отредактированно Targarien (23.09.2013 11:57:11)

Неактивен

 

#2 23.09.2013 22:01:17

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Выборка из таблицы по критерию совпадения из двух других таблиц

По идее должно работать так (хоть и медленно)

SELECT p.image, p.name, p.descr, p.addr, p.phones, p.comment
FROM providers AS p JOIN reference AS r
ON p.id = r.prov_id WHERE
AND r.serv_id = (SELECT services.id FROM services WHERE services.name = 'service')
AND r.city_id = (SELECT cities.id FROM cities WHERE cities.name = 'city');


Приведите результаты
show create table `имя таблицы`;
для ваших таблиц и тестовые данные на десяток строк в виде
insert into ....

Неактивен

 

#3 23.09.2013 22:47:48

Александр Трофимов
Завсегдатай
Откуда: Юрмала
Зарегистрирован: 19.09.2011
Сообщений: 95

Re: Выборка из таблицы по критерию совпадения из двух других таблиц

Вообще правильней было бы из HTML формы выдавать сразу ID города и сервиса, а не отбирать по именам.
И мне непонятны вложенные запросы, зачем они здесь?

SELECT
    p.image,
    p.name,
    p.descr,
    p.addr,
    p.phones,
    p.comment,
    'service' as service_name,
    'city' as city_name  
FROM
    providers AS p
    JOIN reference AS r ON (r.prov_id=p.id)
    JOIN services AS s ON (r.serv_id=s.id)
    JOIN cities AS c ON (r.city_id=c.id)
WHERE
    s.name='service'
    AND c.name='city'


А в идеале, если все ID передать из HTML формы:

SELECT
    p.image,
    p.name,
    p.descr,
    p.addr,
    p.phones,
    p.comment,
    s.name as service_name,
    c.name as city_name  
FROM
    providers AS p
    JOIN reference AS r ON (r.prov_id=p.id)
    JOIN services AS s ON (r.serv_id=s.id)
    JOIN cities AS c ON (r.city_id=c.id)
WHERE
    r.id=$service_id
    AND c.id=$city_id

Неактивен

 

#4 24.09.2013 09:13:23

Targarien
Участник
Зарегистрирован: 23.09.2013
Сообщений: 7

Re: Выборка из таблицы по критерию совпадения из двух других таблиц

vasya написал:

По идее должно работать так (хоть и медленно)

SELECT p.image, p.name, p.descr, p.addr, p.phones, p.comment
FROM providers AS p JOIN reference AS r
ON p.id = r.prov_id WHERE
AND r.serv_id = (SELECT services.id FROM services WHERE services.name = 'service')
AND r.city_id = (SELECT cities.id FROM cities WHERE cities.name = 'city');


Приведите результаты
show create table `имя таблицы`;
для ваших таблиц и тестовые данные на десяток строк в виде
insert into ....

Для сокращения писанины я Вам лучше приложу файл экспорта данных из базы. Это и есть тестовый пример, потому что реальную базу данных еще предстоит наполнить.

Неактивен

 

#5 24.09.2013 09:52:18

Targarien
Участник
Зарегистрирован: 23.09.2013
Сообщений: 7

Re: Выборка из таблицы по критерию совпадения из двух других таблиц

Александр Трофимов написал:

Вообще правильней было бы из HTML формы выдавать сразу ID города и сервиса, а не отбирать по именам.
И мне непонятны вложенные запросы, зачем они здесь?

Вложенные запросы появились потому, что мне хотелось из HTML выдавать имена, хотя это и не получилось. Кстати, из формы действительно выдаются ID'ы и это работает, но пользоваться ID'ами не совсем хорошо, так как требуется соответствие между порядком следования идентификаторов таблиц в базе данных и порядком расположения данных в операторах OPTION формы. Хотелось бы сохранить универсальность, то есть компот отдельно, а мухи - отдельно.

Неактивен

 

#6 24.09.2013 10:34:50

Александр Трофимов
Завсегдатай
Откуда: Юрмала
Зарегистрирован: 19.09.2011
Сообщений: 95

Re: Выборка из таблицы по критерию совпадения из двух других таблиц

Targarien написал:

Александр Трофимов написал:

Вообще правильней было бы из HTML формы выдавать сразу ID города и сервиса, а не отбирать по именам.
И мне непонятны вложенные запросы, зачем они здесь?

Вложенные запросы появились потому, что мне хотелось из HTML выдавать имена, хотя это и не получилось. Кстати, из формы действительно выдаются ID'ы и это работает, но пользоваться ID'ами не совсем хорошо, так как требуется соответствие между порядком следования идентификаторов таблиц в базе данных и порядком расположения данных в операторах OPTION формы. Хотелось бы сохранить универсальность, то есть компот отдельно, а мухи - отдельно.

Порядок следования данных легко сортируется при выборке из БД.

SELECT
    id,
    name
FROM
    cities
ORDER BY
    name

В этом случае города будут отсортированы по (скорее всего латинскому) алфавиту и соответствующие ID к ним. И не надо никаких порядков следования. Пользоваться ID'ами необходимо: код безопасней, строка адреса страницы короче.

Неактивен

 

#7 24.09.2013 17:34:01

Targarien
Участник
Зарегистрирован: 23.09.2013
Сообщений: 7

Re: Выборка из таблицы по критерию совпадения из двух других таблиц

Александр Трофимов написал:

Порядок следования данных легко сортируется при выборке из БД.

SELECT
    id,
    name
FROM
    cities
ORDER BY
    name

В этом случае города будут отсортированы по (скорее всего латинскому) алфавиту и соответствующие ID к ним. И не надо никаких порядков следования. Пользоваться ID'ами необходимо: код безопасней, строка адреса страницы короче.

Спасибо, учту на будущее. Только сортировка мне будет нужна по кириллице.

Неактивен

 

#8 24.09.2013 17:43:28

Александр Трофимов
Завсегдатай
Откуда: Юрмала
Зарегистрирован: 19.09.2011
Сообщений: 95

Re: Выборка из таблицы по критерию совпадения из двух других таблиц

Вы проверьте, должно работать в актуальных версиях MySQL.

Можно добавить в таблицу с городами колонку «sort» в которой указать порядок сортировки. Это по-любому будет лучшее решение, чем использовать названия городов для отбора. И так же с услугами.

Отредактированно Александр Трофимов (24.09.2013 17:45:28)

Неактивен

 

#9 25.09.2013 20:38:32

Targarien
Участник
Зарегистрирован: 23.09.2013
Сообщений: 7

Re: Выборка из таблицы по критерию совпадения из двух других таблиц

Александр Трофимов написал:

Вы проверьте, должно работать в актуальных версиях MySQL.

Можно добавить в таблицу с городами колонку «sort» в которой указать порядок сортировки. Это по-любому будет лучшее решение, чем использовать названия городов для отбора. И так же с услугами.

Спасибо, - с этим все понятно. Может быть поможете с еще одной "заковыкой"?

В таблице для провайдеров есть столбец site, в котором хранится укороченный URL в виде www.somesite.by и другой столбец (name), в котором находится название сайта. Я пытаюсь  сформировать URL-ссылку в своем скрипте (get_data.php):


<?php
... // подключаюсь к MySQL
... // присоединяюсь к своей БД
... // формирую запрос к базе данных
... // выполняю запрос и получаю результат запроса в $result
... // далее в цикле
  $row=mysql_fetch_array($result);
?>
...
  <a href="http://<?php echo $row['site'];?>"><?php echo row['name'];?></a>
...
<?php

... // отключаюсь

?>

Это не работает - я получаю вот такое сообщение об ошибке:
Parse error: syntax error, unexpected '[', expecting ',' or ';' in get_data.php on line 106

В частности, команда echo $row['site']; ничего не выводит вообще. И сколько я ни рылся в инете, ответа не нашел. Может быть все дело в точках?

Отредактированно Targarien (25.09.2013 20:44:37)

Неактивен

 

#10 25.09.2013 21:18:13

deadka
Администратор
Зарегистрирован: 14.11.2007
Сообщений: 2422

Re: Выборка из таблицы по критерию совпадения из двух других таблиц

Targarien написал:

Это не работает - я получаю вот такое сообщение об ошибке:

Parse error: syntax error, unexpected '[', expecting ',' or ';' in get_data.php on line 106

В частности, команда echo $row['site']; ничего не выводит вообще. И сколько я ни рылся в инете, ответа не нашел. Может быть все дело в точках?

А что находится на 106-й строке? Вы код полностью приведите, а то без этого трудно, телепатия не прокачана, увы.


Зеленый свет для слабаков, долги отдают только трусы, тру гики работают только в консоли...

Неактивен

 

#11 26.09.2013 14:30:54

Targarien
Участник
Зарегистрирован: 23.09.2013
Сообщений: 7

Re: Выборка из таблицы по критерию совпадения из двух других таблиц

deadka написал:

А что находится на 106-й строке? Вы код полностью приведите, а то без этого трудно, телепатия не прокачана, увы.

Так этот самый оператор и находится в строке 106:


...
106   <a href="http://<?php echo $row['site'];?>"><?php echo row['name'];?></a>
...
 

А полный текст скрипта великоват будет. Смотрите в прилагаемом файле.
Добавлено:
А файл почему-то не приложился. Вынужден выложить скрипт здесь:

<!DOCTYPE>
<html>
<head>
...
</head>

<body>
...

<?php
// Проверяем введенные данные
$service = htmlspecialchars($_POST["serv"]);
$city = htmlspecialchars($_POST["city"]);

// База данных
$host = 'localhost';
$user = '';
$pass = '';
$bd_name = '';

//соединяемся с сервером базы данных
$conn = mysql_connect($host, $user, $pass);  
if (!$conn) {
    echo "Не могу соединиться с БД MySQL: " . mysql_error();
    exit;
}
//выбираем базу данных
if (!mysql_select_db($bd_name)) {
    echo "Не могу найти базу данных $bd_name: " . mysql_error();
    mysql_close($conn);
    exit;
}  
$query = "SELECT p.image, p.name, p.descr, p.addr, p.phones, p.comment";
$query .= " FROM providers AS p, reference AS r";
$query .= " WHERE r.prov_id = p.id";
$query .= " AND r.serv_id = " . "$service";
$query .= " AND r.city_id =  " . "$city";

// Выполняем запрос к базе данных
$result = mysql_query( $query );
if (!$result) {
    echo "Запрос ($query) не выполнился: " . mysql_error();
    mysql_close($conn);
    exit;
}

if (mysql_num_rows($result) == 0) {
    echo "Не найдена ни одна строка! Выходим!";
    mysql_close($conn);
    exit;
}

while($row=mysql_fetch_array($result)) {
?>
100      <div class="content-layout-row">
101        <div class="content-layout-cell layout-item-0" style="width:20%; float:left; padding-top:10px;">
102          <p><img src="../images/micros/<?php echo $row['image'];?>" alt="" width="90" height="60" /></p>
103        </div>
104        <div class="content-layout-cell layout-item-1" style="width:80%; float:left; padding-top:10px;">
105          <table>
106            <tr><td colspan=2><a href="http://<?php echo $row['site'];?>"><?php echo $row['name'];?></a></td></tr>
107            <tr><td colspan=2><?php echo $row['descr'];?></td></tr>
108            <tr><td><?php echo $address;?></td><td style="float:right"><?php echo $row['phones'];?></td></tr>
109            <tr><td><?php echo $row['comment'];?></td></tr>  
110          </table>
111        </div>
112      </div> <!-- /content-layout-row -->
<?php
}
mysql_free_result($result);
ob_end_clean();  //очищает буфер вывода и отключает буферизацию вывода
mysql_close($conn);
?>
...

</body>
</html>
 

Отредактированно Targarien (26.09.2013 15:19:31)

Неактивен

 

#12 26.09.2013 15:31:55

deadka
Администратор
Зарегистрирован: 14.11.2007
Сообщений: 2422

Re: Выборка из таблицы по критерию совпадения из двух других таблиц

После строчки
while($row=mysql_fetch_array($result)) {
добавьте строчку
print "<pre>"; print_r($row); print "</pre>";
И приведите сюда вывод.


Зеленый свет для слабаков, долги отдают только трусы, тру гики работают только в консоли...

Неактивен

 

#13 28.09.2013 09:02:36

Targarien
Участник
Зарегистрирован: 23.09.2013
Сообщений: 7

Re: Выборка из таблицы по критерию совпадения из двух других таблиц

deadka написал:

После строчки
while($row=mysql_fetch_array($result)) {
добавьте строчку
print "<pre>"; print_r($row); print "</pre>";
И приведите сюда вывод.

Вот вывод для одной строки:


Array
(
    [0] => MultiMotors.jpg
    [image] => MultiMotors.jpg
    [1] => Автоцентр Мультимоторс
    [name] => Автоцентр Мультимоторс
    [2] => <a href="http://www.multimotors.by">www.multimotors.by</a>
    [site] => <a href="http://www.multimotors.by">www.multimotors.by</a>
    [3] => Официальный дилер Chevrolet, Opel, Cadillac в РБ. Продажа автомобилей, запасных частей, СТО.
    [descr] => Официальный дилер Chevrolet, Opel, Cadillac в РБ. Продажа автомобилей, запасных частей, СТО.
    [4] => г. Минск, ул. Могилевская 43а (центр города)
    [addr] => г. Минск, ул. Могилевская 43а (центр города)
    [5] => (017)220-44-44, (029)606-89-28, (029)507-58-58
    [phones] => (017)220-44-44, (029)606-89-28, (029)507-58-58
    [6] =>

    [comment] =>

)

Я благодарен всем, кто принял участие в обсуждении этой проблемы. Причиной же ошибки послужила моя невнимательность: в таблице 'providers' был столбец с именем 'site', но я обращался к нему вначале по имени 'cite'. Кроме того, у меня были ошибки в написании оператора в злосчастной строке 106. Я изменил синтаксис так, чтобы вначале формировалась вспомогательная переменная $url:

while($row=mysql_fetch_array($result)) {
$url = "<a href=\"http://" . $row['site'] . '\">' . $row['name'] . '</a>';
?>
...

После исправлений скрипт стал выдавать правильный результат. Думаю, что тему можно считать закрытой.
Еще раз спасибо всем за обсуждение.

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson