Цикл в цикле

max74max

Новичок
Здравствуйте, помогите пожалуйста разобраться и найти ошибку.
Есть таблицы:

PHP:
INSERT INTO `razdely` (`id`, `id_creatora`, `razdel`) VALUES
(1,    '7', '11'),
(2,    '9', '12'),
(3,    '9', '13'),
(4,    '9', '14'),
(5,    '41', '15');

INSERT INTO `dostup` (`id`, `id_usera`, `id_creatora`, `razdel`, `dostup`) VALUES
(1,    '1', '7', '11', '1'),
(2,    '1', '9', '12', '1'),
(3,    '1', '41', '15', '0');


INSERT INTO `users` (`id`, `school_name`) VALUES
(7, 'Школа 1'),
(9, 'Школа 2'),
(41, 'Школа 3');
и php код

PHP:
$baza_id = "1"; //мой id

$result = $mysqli->query("SELECT DISTINCT id_creatora FROM `razdely` ORDER BY id DESC");

 while ($row = mysqli_fetch_assoc($result)) {

$result1 = $mysqli->query("SELECT * FROM `dostup` WHERE `id_usera` = '".$baza_id."' && `dostup` = '1' ORDER BY id ASC LIMIT 1"); // !!! ошибка в этой строке

if ($result1->num_rows >= 1) {

$result2 = $mysqli->query("SELECT * FROM `users` WHERE `id` = '".$row[id_creatora]."' ORDER BY id ASC LIMIT 1");

 while ($row2 = mysqli_fetch_assoc($result2)) {
echo $row2["school_name"]."<br>";
}
}
}
    mysqli_free_result($result);
    mysqli_free_result($result1);
    mysqli_free_result($result2);
Результатом получаю следующие данные:
Школа 1
Школа 2
Школа 3


Хотя Школа 3 быть не должно, т.к. в таблице `dostup` стоит значение 0

Мне нужно чтобы в первом цикле выбирались все id_creatora которые есть но без повторения, во втором цикле отсеивались все кроме тех, к которым у меня (id_usera =1) есть доступ (dostup = 1). А в третьем цикле выводились названия школ из таблице 'users' исходя из выбранных ранее критериев.
Знаю что нужно использовать подготовленные выражения, но хотелось бы понять в чем причина ошибки именно в этом примере. Мне не совсем понятна логика.
 

Valick

Новичок
max74max, есть одно золотое правило "Если у тебя запрос в цикле - значит ты делаешь, что-то не правильно." SQL - это декларативный язык программирования. Само понятие цикл для него противоестественно.
Ещё нельзя взять и просто так налепить таблиц в базу данных. Есть определённые правила для построения архитектуры БД, в том числе и правила нормализации. Процесс начинается с определения хранимых сущностей и выявления связей между ними. И тогда обработку данных можно производить средствами языка SQL на уровне СУРБД.
 

max74max

Новичок
Подсказали вот такое решение.

PHP:
SELECT a.* FROM users a LEFT JOIN dostup b ON a.id = b.id_creatora
    WHERE b.id_usera=1 && b.dostup=1 && !ISNULL(b.id);
Но я не понимаю что такое a. и b. для чего они нужны?
 

max74max

Новичок
Есть определённые правила для построения архитектуры БД, в том числе и правила нормализации.
Вот именно поэтому в таблице users хранятся пользователи, в таблице razdely хранятся сами разделы, а в dostup хранятся доступы.
 

WMix

герр M:)ller
Партнер клуба
я не могу помочь если не понимаешь, читай SQL
 

Valick

Новичок
У тебя id_creatora и razdel в двух таблицах это #ненормально
Писать в SQL запросах && вместо AND это тоже #ненормально
 

max74max

Новичок
У тебя id_creatora и razdel в двух таблицах это #ненормально
Писать в SQL запросах && вместо AND это тоже #ненормально
Во-первых, как ты без этого узнаешь какой раздел к какому CREATE'ару относится.
Во-вторых, как я уже сказал, мне непонятна логика как можно реализовать поставленную задачу, а конкретные #ненормальные ошибки типа && и AND
 

max74max

Новичок
Вопрос решен.

PHP:
$result = $mysqli->query("SELECT DISTINCT a.* FROM `users` a LEFT JOIN `dostup` b ON a.id = b.id_creatora WHERE b.id_usera='1' && b.dostup='1' && !ISNULL(b.id)");

 while ($row = mysqli_fetch_assoc($result)) {
echo $row["school_name"]."<br>";
}
 

Valick

Новичок
я бы поступил вот так (дамп БД прикрепил)
SQL:
SELECT  sc.sc_id
      , sc.sc_name
FROM `user_section` us
  LEFT JOIN `school_section` ss ON us.se_id = ss.se_id
  LEFT JOIN `schools` sc ON sc.sc_id = ss.sc_id
WHERE us.`u_id` = 1
GROUP BY sc.sc_id
 

Вложения

Сверху