MySQL: "равно, но не ограничиваясь этим"

Автор Jerry, 05 июля 2008, 00:17:23

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

Jerry

Это конечно не в тему, но тут нет раздела по запросам БД. :(

Можете помочь сделать такой код верным?
А запросе в самом конце после WHERE идет такой кусок
AND mf.ID_MSG = t.ID_FIRST_MSG
И надо добавить после этого
AND t.ID_POLL = p.ID_POLL
Но с таким запросом не будут выбераться строки, где t.ID_POLL = 0!
Как сделать выбор строк с условием t.ID_POLL = p.ID_POLL, если t.ID_POLL не равен 0, и без условия, если равен 0?

Вот, что мне нужно (примерная идея):
AND (t.ID_POLL = p.ID_POLL OR t.ID_POLL=0)
Но это не работает! Я пытался еще так:
AND (t.ID_POLL = p.ID_POLL || t.ID_POLL=0)
И так:
AND t.ID_POLL = p.ID_POLL || t.ID_POLL=0
И так:
AND t.ID_POLL = p.ID_POLL OR t.ID_POLL=0

Но ничего не работает! :(
Как сделать верно? В MySQL вообще есть вложенные условия?

Нужно, чтобы было как это (на C++):
&& (t.ID_POLL==p.ID_POLL || t.ID_POLL==0)
Тока запросом MySQL. Ну как же это сделать? Кто может подсказать?

bbbbbb

можешь написать что нужно сделать???

я так понимаю нужно через связь с другой таблицей...
и что такое "0"? какой ноль?

Jerry

0 - просто обычный int. Не false... просто 0.
Нужно сделать вложенное условие прямо в запросе.
Я написал пример на C++. Вот на php был бы:
&& (t.ID_POLL==p.ID_POLL || t.ID_POLL==0)

Хотя то же самое...
После всех AND надо добавить t.ID_POLL=p.ID_POLL, но чтобы t.ID_POLL=0 тоже брались. или - или.

Но просто OR не выходит, наверное потому, что до них были AND, так что, как вложенные делать в MySQL?

bbbbbb

 ???
ну в талицах некоторых которых я использовал, нету 0, все начинаеться с 1


может есть смысл сделать нормально "перелить" таблицу чтобы начиналось с 1 ....

зачем тебе ИЛИ, может надо  И?

а если так   
AND t.ID_POLL = p.ID_POLL AND t.ID_POLL=0

или сделать UNION еще один запрос

тоесть просто:
p.ID_POLL=0 limit 1

Jerry

#4
AND t.ID_POLL = p.ID_POLL AND t.ID_POLL=0
Как по вашему он будет равен p.ID_POLL и одновременно не равен?! :o
0 - это отсутствие голосование. Как оно может быть не 0 и 0 одновременно?
Это условие тождественно невыполнимо.

p.ID_POLL=0 limit 1
А это вообще выдаст пустой результат, да и с лимитом 1. :(
Т.к. в таблице polls нет 0. А в topics как раз есть.
А нужен список постов, без лимита. И с условием ИЛИ. p.ID_POLL - это {db_prefix}polls_ID_POLL, а t.ID_POLL, это то же, только в posts.
Вы о чем? ???

Цитироватьможет есть смысл сделать нормально "перелить" таблицу чтобы начиналось с 1 ....
И зачем мне 1? Это как раз ненормально будет. Нормально, когда есть 0. И в topics ID_POLL 0 - отсутствие голосования, а в polls нет.

Кто знает все-таки, как сделать вложенное "или"?

Наверсное, вот так понятнее будет - Вот полная картина происходящего:
Запрос из MessageIndex отредактированный:
$result = db_query("
SELECT
t.ID_TOPIC, t.numReplies, t.locked, t.numViews, t.isSticky, t.ID_POLL,
" . ($user_info['is_guest'] ? '0' : 'IFNULL(lt.ID_MSG, IFNULL(lmr.ID_MSG, -1)) + 1') . " AS new_from,
t.ID_LAST_MSG, ml.posterTime AS lastPosterTime, ml.ID_MSG_MODIFIED,
ml.subject AS lastSubject, ml.icon AS lastIcon, ml.posterName AS lastMemberName,
ml.ID_MEMBER AS lastID_MEMBER, IFNULL(meml.realName, ml.posterName) AS lastDisplayName,
t.ID_FIRST_MSG, mf.posterTime AS firstPosterTime,
[b]p.votingLocked, p.expireTime,[/b]
mf.subject AS firstSubject, mf.icon AS firstIcon, mf.posterName AS firstMemberName,
mf.ID_MEMBER AS firstID_MEMBER, IFNULL(memf.realName, mf.posterName) AS firstDisplayName,
LEFT(ml.body, 384) AS lastBody, LEFT(mf.body, 384) AS firstBody, ml.smileysEnabled AS lastSmileys, memf.shop_nameStyle,
mf.smileysEnabled AS firstSmileys
FROM ({$db_prefix}topics AS t, {$db_prefix}messages AS ml, {$db_prefix}messages AS mf, [b]{$db_prefix}polls AS p[/b])
LEFT JOIN {$db_prefix}members AS meml ON (meml.ID_MEMBER = ml.ID_MEMBER)
LEFT JOIN {$db_prefix}members AS memf ON (memf.ID_MEMBER = mf.ID_MEMBER)" . ($user_info['is_guest'] ? '' : "
LEFT JOIN {$db_prefix}log_topics AS lt ON (lt.ID_TOPIC = t.ID_TOPIC AND lt.ID_MEMBER = $ID_MEMBER)
LEFT JOIN {$db_prefix}log_mark_read AS lmr ON (lmr.ID_BOARD = $board AND lmr.ID_MEMBER = $ID_MEMBER)"). "
WHERE " . ($pre_query ? 't.ID_TOPIC IN (' . implode(', ', $topic_ids) . ')' : "t.ID_BOARD = $board") . "
AND ml.ID_MSG = t.ID_LAST_MSG
AND mf.ID_MSG = t.ID_FIRST_MSG
[b]AND t.ID_POLL = p.ID_POLL[/b]
ORDER BY " . ($pre_query ? "FIND_IN_SET(t.ID_TOPIC, '" . implode(',', $topic_ids) . "')" : (!empty($modSettings['enableStickyTopics']) ? 'isSticky' . ($fake_ascending ? '' : ' DESC') . ', ' : '') . $_REQUEST['sort'] . ($ascending ? '' : ' DESC')) . "
LIMIT " . ($pre_query ? '' : "$start, ") . "$maxindex", __FILE__, __LINE__);


Туда добавлено это:
p.votingLocked, p.expireTime,
, {$db_prefix}polls AS p
AND t.ID_POLL = p.ID_POLL



Проблема в том, что запрос возвратит только голосования (только те темы, где t.ID_POLL = p.ID_POLL).
А нужно привязать t.ID_POLL к p.ID_POLL, но при этом оставить выдачу постов без голосования, где t.ID_POLL = 0.
Т.е. чтобы выдавались даже те строки, где t.ID_POLL=0, но если пост - голосование (t.ID_POLL = p.ID_POLL), то row['votingLocked'] будет иметь такое значение, как в таблице polls, в которой ID_POLL равен ID_POLL из таблицы topics.

AND (t.ID_POLL = p.ID_POLL OR t.ID_POLL=0)
- такое не работает. :(

Вот как такое
a==b && (x==t || x==0)
записать на MySQL? К примеру.

Или может в MySQL есть оператор, означающий "одно из этих значений" и можно вписать через запятую значения, равенство любому из которых возвращает true (что-то слышал о функции IN, но не нашел)? Как сделать то, что выше написано? Кто-нибудь знает?







Отредактировано:
Я понял, что это сделать это в одном запросе невозможно. И через case then не вышло. :(
Всё решилось созданием второго запроса:

$result2 = db_query("
SELECT p.votingLocked, p.expireTime
FROM ({$db_prefix}topics AS t, {$db_prefix}polls AS p)
WHERE p.ID_POLL = t.ID_POLL");

while ($row2 = mysql_fetch_assoc($resul2))
{
$votingLocked[$row2['ID_POLL']]=$row2['votingLocked'];
$expireTime[$row2['ID_POLL']]=$row2['expireTime'];
}
mysql_free_result($result);


Хотел сделать в один запрос, но с условием "p.ID_POLL = t.ID_POLL" в результатах пропадают обычные темы без голосований.

bbbbbb

тогда не знаю, но кажеться что решаеться!

ЗЫ а какой тип таблиц? там "0" во многих таблицах не может быть!!

Jerry

В каких многих? prefix_topics содержит 0 (обычный INT) в ID_POLL, когда у темы нет голосования.
Я уже сделал двумя запросами, всё работает.
Первым запросом возвращается полный список всех тем, независимо от того, есть ли голосование (0 или не 0 ID_POLL). А второй запрос уже выберает не 0 и такие, что topics.ID_POLL=polls.ID_POLL. Уже всё ОК.

P.S. Я просто сделал, чтобы иконки идущего и завершенного голосования различались в списке тем.

bbbbbb

#7
ну у меня такой проблем не было, но я вижу что это решаемо!!

у меня все решалось, сделай может отдельный запрос, чтобы определить если то голосование или нет, еще по гугли!!

спроси у diiger'a   ;D ;D 2funny

Jerry

Зачем что-то определять? Мне нужен был список тем с голосованиями и без. Но чтобы если есть голосование, то можно узнать его votingLocked.
ЦитироватьПроблема в том, что запрос возвратит только голосования (только те темы, где t.ID_POLL = p.ID_POLL).
А мне нужны были ВСЕ темы. Поэтому я разбил на 2 запроса: 1 узнает список тем, другой свойства голосований тех тем, где есть голосования.

Чтобы уместить в один запрос, нужно вложенное ИЛИ (OR). Я про него и спрашивал, но никто не знает, как сделать такое условие: "a==b && (x==t || x==0)" в MySQL запросе. Вложенные ИЛИ не работают (или внутри скобок после "и").

Jerry

Я нашел спосоооб!!!  :D Если нужно привязать одно поле к другом без обязательного присутствия любого из них, нужно использовать LEFT JOIN! :D
LEFT JOIN {$db_prefix}polls AS p ON (t.ID_POLL = p.ID_POLL)
Это я сделал по аналогии с другими запросами SMF.
Просто догадался, но описания этого оператора не нашел нигде! Поисковики дают тока его детали, а не описание.
Кто знает, что же делает этот оператор JOIN и это направление LEFT?
Он для того и предназначен, чтобы привязывать одно поле к другом без опязательного присутствия (в отличие от WHERE)? И зачем left и right? Что за лево-право?

Mavn

SimpleMachines Russian Community Team
п.1 Пройду курсы гадалок для определения исходного кода по скриншоту.

п.2 У вас нет желания читать правила раздела, у меня нет желания одобрять темы, которые не соответствуют этим правилам.

Jerry

Да я искал статьи, но и здесь не рассказывается, для чего предназначен JOIN. Только особенности и подробности, а что он делает - не сказано.
Остается догадываться, но это только догадки. Ну это ладно...

В чем же разница LEFT и RIGHT? Написано "RIGHT JOIN работает аналогично LEFT JOIN".
Но что значат вообще эти направления? Это влияет на порядок проверки, положение столбца результата или что?  :o