Следната задачка =)

djman

Registered
Имам следното:

users:
Код:
name | stars
---------------
user1 | 1,2
user2 | 1,3,5
user3 | 2,4

stars:
Код:
star | img | title
------------------- 
   1   |1.jpg| първа звезда
   2   |2.jpg| втора звезда
...

Как да ги разгранича, че да получа следния резултат:
първа звезда
user1, user2

втора звезда
user1, user3

Надявам се, че ме разбрахте =) Благодаря предварително!
 
$query = mysql_query('SELECT * FROM users');//заявка да ти вземе потребителите
while($r = mysql_fetch_assoc($query))
{
$stars = explode(',', $r['stars']);
$users[] = array('name'=>$r['name'], 'stars'=>$stars);
}

foreach($users as $k=>$v)
{
for($i = 0; $i < count($v['stars']); $i++)
{
$q = mysql_query('SELECT * FROM stars WHERE star="'.$v['stars'][$i].'"');
$r = mysql_fetch_assoc($q);
$users[$k]['stars'][$i] = array('img'=>$r['img'], 'title'=>$r['title']);
}
}

print_r($users);
 
Не че е невъзможно, но така направено, структурата на базата данни е грешна, не е оптимизирана и ще затрудняваш DB сървъра излишно. За получените звезди би трябвало да имаш запис на отделен ред за всеки потребител и за всяка негова звезда:

name | stars
---------------
user1 | 1
user1 | 2
user2 | 1
user2 | 3
user2 | 5
user3 | 2
user3 | 4

Така вече сигурно ти е ясно как ще стане?

Конкретно на въпроса ти:

1. Първо взимаш видовете звезди от втората таблица и започваш да листваш. За всеки тип звезда, търсиш потребителите, които имат такъв запис, но обърни внимание на самото търсене с wildcard - в началото, в края, по средата:

Код:
$stars = mysql_query("select * from stars");
while($star_row = mysql_fetch_array($stars)){
    $users = "select 
                                   name 

                        from 
                                    users 

                        where 
                                     (stars = '".$star_row[star]."') OR 
                                     (stars like '".$star_row[star].",%') OR 
                                     (stars like '%,".$star_row[star]."')  OR 
                                     (stars like '%,".$star_row[star].",%') ";
}
 
Миро, имам няколко коментара към твоето решение:

1. Тръгнал си по обратния път - от потребителите към звездите, съответно и резултата не му върши работа и отново трябва да се прилага някаква обратна логика за да може от твоя резултат да се изведат първо звездите, после потребителите, които имат тези звезди. Човека иска да листне видовете звезди и кои потребители са получили тези звезди, а ти му връщаш потребителите и какви звезди има всеки потребител.

2. Вярно, че структурата на базата му данни е сбъркана, но ти правиш страшно много заявки - за всяка звезда и за всеки потребител.

3. В програмирането броенето винаги започва от нула. Ако спазваш това правило, никога отново няма да направиш тази грешка:

Код:
$stars = explode(',', $r['stars']);

....

for($i = 1; $i <= count($v['stars']); $i++)
С твоя код, ти винаги пропускаш първия елемент в началото на итерацията, а пък на края проверяваш за несъществуващ елемент.
 
exec каза:
exec каза:
Всичко беше добре обяснено, но накрая тая заявка твоята не можах да я разбера :idea: Може и в мене да е грешката, но с тази заявка не е ли далеч по-лесно :?:
SELECT
s.*,GROUP_CONCAT(u.name) AS stars
FROM
stars AS s
LEFT JOIN users AS u ON u.star = s.id
GROUP BY s.id
 
Благодаря ви много!
До колкото виждам, втората заявка се явява в цикъл - не беше ли "вредно" това? Или, вероятно, бъркам с нещо друго... :roll:

П.С. Утре ще пробвам, че днес съм капнал... Благодаря пак, ако има нещо ще питам:)
 

Back
Горе