Задавайте вопросы, мы ответим
Вы не зашли.
Есть БД со след. структурой таблиц:
CREATE TABLE IF NOT EXISTS users(
uid INT AUTO_INCREMENT KEY,
nik TEXT,
email TEXT,
pass TEXT
CREATE TABLE IF NOT EXISTS line(
lid INT AUTO_INCREMENT PRIMARY KEY,
eid INT,
bet TEXT,
kef TEXT,
refreshtime TIMESTAMP(12)
CREATE TABLE IF NOT EXISTS events(
eid INT AUTO_INCREMENT KEY,
sport TEXT,
data TIMESTAMP(12),
teams TEXT,
itog TEXT DEFAULT ''
CREATE TABLE IF NOT EXISTS bets(
bid INT AUTO_INCREMENT KEY,
lid INT,
uid INT,
timebet TIMESTAMP(12),
eid INT
Связь между таблицами по одноименным полям
Нужно написать такой запрос SELECT, чтобы получить все events.* , для которых известно users.uid и bets.uid<>users.uid в таблице. Т.е. имеем некоторое значение uid, по нему находим те строки в таблице bets, которые не равняются uid. И извлекаем соответствующие строки этому в таблице line, а из нее - в таблице events.
В общем, скрипт перегружает сервер. Что я делаю неправильно? Какой запрос тут нужен?
Неактивен
Если перефразировать, то мне нужны все строки из events кроме тех, для которых (events.eid==line.eid) AND (line.lid=bets.lid) AND (bets.uid=$uid). Как это написать?
Неактивен
$query="SELECT events.*
FROM events,users,line,bets
WHERE (
(users.uid=$uid) AND
(users.uid=bets.uid) AND
(line.lid=bets.lid) AND
(events.eid=line.eid) )
"; - этот запрос возвращает все строки, которые удовлетворяют условию, а надо наоборот.
$query="SELECT events.*
FROM events,users,line,bets
WHERE (!(
(users.uid=$uid) AND
(users.uid=bets.uid) AND
(line.lid=bets.lid) AND
(events.eid=line.eid) ))
"; - вешает сервак, не хватает памяти. Видимо, слишком много вариантов удовлетворяет условию. Ничего не понимаю...
Неактивен
Именно так и написать, только ключики нужны на «одноименных полях».
Отдельные. И после добавления ключиков EXPLAIN над запросом покажите
Неактивен
paulus написал:
Именно так и написать, только ключики нужны на «одноименных полях».
Отдельные. И после добавления ключиков EXPLAIN над запросом покажите
Про EXPLAIN прочитал, хорошая штука, буду пользоваться!
А вот про ключи - не понял. Их надо при создании таблиц указывать? (но вроде тогда выскакивает ошибка: типа мультипл кей, т.е. дофига ключей). Значит, в другом месте? В SELECT'е это указывается? Не могу найти вообще в инете хорошую литературу, чтобы там было много примеров с SELECT'ами. Может, подскажете что?
Неактивен
ALTER TABLE line ADD INDEX(eid);
ALTER TABLE bets ADD INDEX(lid), ADD INDEX(uid), ADD INDEX(eid);
Неактивен
Сделал, но теперь материться, что не хватает памяти.
Неактивен
Кто?
Неактивен
Если я правильно понял, то где-то здесь надо всобачить еще JOIN
Неактивен
Накропал запрос:
$query="SELECT e.eid, e.sport, e.teams, e.data, u.nik
FROM events e
INNER JOIN line l ON l.eid=e.eid
INNER JOIN bets b ON b.lid=l.lid
INNER JOIN users u ON u.uid!=b.uid
LIMIT 2500
";
Блин, он выводит все строки из events, но умножает их на строки users. А мне не надо умножать, мне только список events получить...
Неактивен
Что JOIN, что запятая — всё едино. Запросы у Вас хорошие были,
а индексов не хватало.
SELECT * FROM a, b WHERE a.field = b.field
и
SELECT * FROM a JOIN b ON a.field = b.field
эквивалентны.
Неактивен
Я знаю, что эквивалентные, но они не работают так, как надо
Неактивен
Я правильно понимаю, что Вы хотите вот это?
SELECT …
FROM bets b JOIN events e USING (eid)
WHERE b.uid != …
Обратите внимание, что eid есть как в events, так и в bets и в lines —
похоже, где-то он лишний.
Неактивен
Ну и че, не работает оно, выводит пустой результат!
eid - почему лишний? он будет лишний, если сделать так, чтобы таблицу events можно было корректно связать с line по eid, потом line связать с bets по lid, вот тогда будет лишнее bets.eid.
Но проблема в том, что я не знаю, как связать три таблицы по этим двум столбцам.
Неактивен
Пишу вот:
$query="SELECT e.eid
FROM events e
JOIN line l USING (eid)
JOIN bets b USING (lid)
WHERE
b.uid!=$uid
ORDER BY e.eid
";
Где я не прав?
Неактивен
Может, я ДИма БИЛан, но пришлось написать такую дурость на РНР для реализации вышеуказанного:
// Создаем полный список
$r=mysql_query("SELECT events.eid FROM events");
for($list1=array(); $row=mysql_fetch_row($r); $list1[]=$row[0]);
// Список по условию
$r=mysql_query("SELECT DISTINCT e.eid FROM events e,line l,bets b, users u
WHERE e.eid=l.eid AND l.lid=b.lid AND b.uid=$uid");
for($list2=array(); $row=mysql_fetch_row($r); $list2[]=$row[0]); var_dump($list2);
// Разница между этими списками
$eids=array();
foreach($list1 as $v) if (!in_array($v,$list2)) $eids[]=$v;
Неактивен
Как я понимаю, ничего более изящного никто не придумает?
Неактивен
PHP — чрезвычайно не изящный язык. Если добавите побольше ентеров —
может выглядеть чуть красивее Ну и читабельнее станет.
А с базой подумайте все-таки: подозреваю, что bets.eid лишнее.
Неактивен
paulus написал:
А с базой подумайте все-таки: подозреваю, что bets.eid лишнее.
Да, лишнее. Изначально и не было. Потом добавил временно для тестов. Сейчас опять удалено.
Неактивен
Ну, тогда Ваш запрос выглядит нормально
Неактивен