Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Сложный запрос на mySQL. Как сделать?

2.0K
23 октября 2004 года
Prokur
85 / / 13.10.2004
можно ли сделать на mysql чтобы SELECT делался из SELECT. пример:
Цитата:
SELECT * FROM [ SELECT id from table where a=b] order by id


Как можно сделать не прибегая к сторониим обработчиком?

2.0K
25 октября 2004 года
Prokur
85 / / 13.10.2004
Неужели за двое суток ни один, кто знает как это сделать, сюда не зашел :) Или это нереально?
265
25 октября 2004 года
Gauss
975 / / 20.02.2000
Цитата:
Originally posted by Prokur
можно ли сделать на mysql чтобы SELECT делался из SELECT. пример:

Как можно сделать не прибегая к сторониим обработчиком?

Помоему mysql не поддерживает вложенные запросы, то что ты хочешь получить делается через временные таблицы, хотя внимательно посмотрев твой запрос я просто даже не понимаю чего ты хочешь получить, во вложенном запросе ты получаешь список id соответствующих твоему условию, а во внешнем просто выводишь его-же без каких либо изменений

10
25 октября 2004 года
Freeman
3.2K / / 06.03.2004
Цитата:
Originally posted by Prokur
можно ли сделать на mysql чтобы SELECT делался из SELECT. пример:


Выясни, поддерживает ли твоя версия MySQL стандарт SQL92. Выборка из SELECT является одним из требований соответствия этому стандарту.

2.0K
26 октября 2004 года
Prokur
85 / / 13.10.2004
Объясню вам мою проблему и задачу.
Имеются две таблицы в базе, с разными полями (см. ниже). Мне надо сделать выборку используя данные из обоих таблиц.
Это система голосвания по галлерее.
В первой таблице список всех голосов, за разные картинки - оценка(note), время(timestamp), ИП-адресс (ip_addr).
А во второй таблице список этих картинок (id), суммарная оценка (note) и кол-во голосов за эту картинку(votes).
Так вот, мне нужна выборка ID картинок, за которые не голосовал конкретный ИП-адресс.
Как бы лучше это сделать? Средствами MySQL, чтобы не грузить большой список голосов которые пренадлежат этому ИП или тем более которые не принадлежат.
10
26 октября 2004 года
Freeman
3.2K / / 06.03.2004
Цитата:
Originally posted by Prokur

В первой таблице список всех голосов, за разные картинки - оценка(note), время(timestamp), ИП-адресс (ip_addr).
А во второй таблице список этих картинок (id), суммарная оценка (note) и кол-во голосов за эту картинку(votes).
Так вот, мне нужна выборка ID картинок, за которые не голосовал конкретный ИП-адресс.


Непонятно, как связаны между собой таблицы, и для чего вообще нужна вторая таблица. Достаточно добавить ID картинки в первую таблицу, и надобность во второй таблице отпадает.
Вообще, хранить в таблице количество записей в другой таблице нарушает принцип реляционной нормализации данных. Или я неправильно понял задачу. Вроде бы количество голосов и средняя оценка пользователей для каждой картинки должны вычисляться из суммарных данных по каждому голосованию с использованием group by.

2.0K
26 октября 2004 года
Prokur
85 / / 13.10.2004
Цитата:
Originally posted by smartsoft
Непонятно, как связаны между собой таблицы, и для чего вообще нужна вторая таблица.


В первой таблице лог голосований, для защиты от повторного голосования от одного IP. А вторая таблица это список картинок

Цитата:
Достаточно добавить ID картинки в первую таблицу, и надобность во второй таблице отпадает.

Уже есть, - car_id это id картинки

Цитата:
Вроде бы количество голосов и средняя оценка пользователей для каждой картинки должны вычисляться из суммарных данных по каждому голосованию с использованием group by.


Это очень долгая выборка, если надо каждый раз выводить данные по 20-50 фоткам. Я храню суммы во второй таблице, что значительно, в тысячи раз убыстряет процесс.

368
27 октября 2004 года
rostyslav
629 / / 13.07.2004
 
Код:
SELECT DISTINCT t2.id, t1.ip_addr
FROM TABLE1 t1, TABLE2 t2
WHERE t2.id NOT IN(SELECT car_id FROM table1 WHERE ip_addr=t1.ip_addr)
ORDER BY 2, 1
Но запрос неэффективен. Нужна была бы временная таблица, которая содержала бы уникальные ip_addr.
2.0K
27 октября 2004 года
Prokur
85 / / 13.10.2004
Не работает :( чтобы я не делал mysql не нравилось NOT IN (..) соеденение :(
По отдельности запросы работали, но вместе не идут.
А что таое distinct?
Цитата:
Но запрос неэффективен. Нужна была бы временная таблица, которая содержала бы уникальные ip_addr.


Почему не эффективен? Что значит временная таблица? Создать новую таблицу только для временного результата? но как опять же соеденить это всё в один запрос.

368
27 октября 2004 года
rostyslav
629 / / 13.07.2004
Цитата:
Originally posted by Prokur
Не работает :( чтобы я не делал mysql не нравилось NOT IN (..) соеденение :(
По отдельности запросы работали, но вместе не идут.
А что таое distinct?

Почему не эффективен? Что значит временная таблица? Создать новую таблицу только для временного результата? но как опять же соеденить это всё в один запрос.


DISTINC - возвращаются только уникальные записи.

Под временной таблицей, я подразумевал таблицу, которая существует только в памяти. Не знаю есть ли такое в MySql.

Неэффективен, потому что, сколько раз встречается ip_addr в table1, столько раз находятся для него картинки, на которых он не голосовал.

Соединить можно, но пока NOT IN не работает...Но должен работать. Что пишет MySql, почему ему не нравится NOT IN?

2.0K
27 октября 2004 года
Prokur
85 / / 13.10.2004
Syntax error.
Все перепробовал. Интересно, что по отдельности запросы работают а с соедением NOT IN или просто IN нет :(
368
28 октября 2004 года
rostyslav
629 / / 13.07.2004
Цитата:
Originally posted by Prokur
Syntax error.
Все перепробовал. Интересно, что по отдельности запросы работают а с соедением NOT IN или просто IN нет :(


У тебя mySql 4.1 или выше? Начиная c 4.1 mySql поддерживает подзапрос в списке.

4
28 октября 2004 года
mike
3.7K / / 01.10.2002
Цитата:
Originally posted by Prokur
Syntax error.
Все перепробовал. Интересно, что по отдельности запросы работают а с соедением NOT IN или просто IN нет :(



Как меня поражают люди, которым все на блюдечке подавай. Скопировал запрос и не работает ?? И не заработает, пока ты не поймешь его суть. NOT IN при правильном использовании работает в MySql (используй поиск по форуму, совсем недавно была тема)

Вложенные запросамы тут и не нужны, хотя MySql 4.1 их поддерживает.

368
28 октября 2004 года
rostyslav
629 / / 13.07.2004
На счет EXISTS ничего не пишет help. Может он подзапросы поддерживает и в младших версиях
 
Код:
SELECT DISTINCT t2.id, t1.ip_addr
FROM TABLE1 t1, TABLE2 t2
WHERE  NOT EXISTS (SELECT car_id FROM table1 WHERE ip_addr=t1.ip_addr AND car_id=t2.id)
ORDER BY 2, 1
2.0K
28 октября 2004 года
Prokur
85 / / 13.10.2004
mike, вместо того, чтобы поражаться дай ссылочку, на эту ветку. Я понимаю что делаю, просто это в первый раз, если бы я просто копировал и смотрел, то я бы не сидел несколько часов над этим запросом.

rostyslav, попробовав этот пример, получил ругань на слово exists, взял его просто поменял на exist и теперь он начал ругаться на вкладыш, также как при IN.

Версия MySQL 3.23.58
4
28 октября 2004 года
mike
3.7K / / 01.10.2002
Цитата:
Originally posted by Prokur
mike, вместо того, чтобы поражаться дай ссылочку, на эту ветку. Я понимаю что делаю, просто это в первый раз, если бы я просто копировал и смотрел, то я бы не сидел несколько часов над этим запросом.



Ты версию то выяснил ?

2.0K
28 октября 2004 года
Prokur
85 / / 13.10.2004
Цитата:
Originally posted by mike


Ты версию то выяснил ?



да, выяснил, написал в верхнем посте. Можешь этот пост стереть после того как прочтешь

368
28 октября 2004 года
rostyslav
629 / / 13.07.2004
Цитата:
Originally posted by Prokur

rostyslav, попробовав этот пример, получил ругань на слово exists, взял его просто поменял на exist и теперь он начал ругаться на вкладыш, также как при IN.

Версия MySQL 3.23.58


С exists видимо та же самая проблема. Не поддерживает подзапрос.

Если mike не поделится секретом, как выбрать данные без подзапроса, то без временных таблиц не обойтись.
Нужны таблицы
table3(ip_addr int)
table4(ip_addr int, car_id int)

DELETE FROM table3

INSERT INTO table3 SELECT DISTINCT ip_addr FROM table1

DELETE FROM table4

INSERT INTO table4 SELECT t3.ip_addr, t2.id AS car_id FROM table3 t3, table2 t2

SELECT table4.ip_addr, table4.car_id, table1.note FROM table4
LEFT JOIN table1 ON table1.car_id=table4.car_id
AND table4.ip_addr=table1.ip_addr WHERE table1.note IS NULL

2.0K
28 октября 2004 года
Prokur
85 / / 13.10.2004
rostyslav, спасибо огромное за потраченное время, но ничиего не понятно :( Я даже не понял куда вписывать ИП, на который мне надо найти картинки.

можешь пожалуйста объяснить что делает команда LEFT, JOIN?
а лучше всё вместе и с комментариями :(
я не хочу как обезъяна переписывать код.
368
28 октября 2004 года
rostyslav
629 / / 13.07.2004
Цитата:
Originally posted by Prokur
rostyslav, спасибо огромное за потраченное время, но ничиего не понятно :( Я даже не понял куда вписывать ИП, на который мне надо найти картинки.

можешь пожалуйста объяснить что делает команда LEFT, JOIN?
а лучше всё вместе и с комментариями :(
я не хочу как обезъяна переписывать код.


Я думал тебе нужна выборка по всем IP адресам.

Но если только для одного, то mike был прав. Можно без подзапросов

 
Код:
SELECT table2.id, table1.ip_addr FROM table2
LEFT JOIN table1 ON table2.id=table1.car_id AND table1.ip_addr='81.198.79.162'
WHERE table1.ip_addr IS NULL


LEFT JOIN - левое внешнее соединение, добавляются все записи из первой таблицы(table2). А поля, которые должны бы выбыраться из второй таблицы (table1) заполняются с NULL. Что лучше понять, как она работает, выполни запрос без WHERE table1.ip_addr IS NULL
2.0K
02 ноября 2004 года
Prokur
85 / / 13.10.2004
rostyslav, спасибо большое. Ты отец запросов :)) Я покыварялся, но всеравно не очень отчетливо понял, как это дело работает. Если бы кто-то расписал каждый шаг, который делает база, прежде чем выдать такой запрос.
А так работет - спасибо.
368
03 ноября 2004 года
rostyslav
629 / / 13.07.2004
table2 содержит все car_id.

"нормальный запрос"
SELECT table2.id, table1.ip_addr FROM table2, table1
WHERE table2.id=table1.car_id AND table1.ip_addr='81.198.79.162'

выбирает все id из table2, на которых '81.198.79.162' дал оценку.

Левое внешнее соединение

SELECT table2.id, table1.ip_addr FROM table2
LEFT JOIN table1 ON table2.id=table1.car_id AND table1.ip_addr='81.198.79.162'

к этим записям еще добавляет, оставшиесся id из table2, а вместо table1.ip_addr берет NULL, т.е. это те id, на которые '81.198.79.162' не дал оценку.

условие WHERE table1.ip_addr IS NULL
в результирующем наборе оставляет, как раз эти записи.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог