Модераторы: LSD

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помогите с запросом 
:(
    Опции темы
alexey9
  Дата 8.10.2006, 17:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 4.10.2006

Репутация: нет
Всего: нет



Код

SELECT 
  data.id AS data_id, 
  data.parent_id AS data_parent_id, 
  data.ref_id, 
  data.data_ref,
  flds_names.order_id,
  flds_data.id,
  flds_data.pref_id,
  flds_data.ref,
  flds_data.data_ru,
  flds_names.id AS fn_id,
  flds_names.name_ru
FROM
  data,
  flds_data,
  flds_names
WHERE
  flds_data.pref_id <> 255 AND
  flds_data.ref = data.id AND
  flds_data.fref_id = flds_names.id AND
  data.id=$curPosition AND
  data.parent_id=$curParentID
ORDER BY
   flds_names.order_id

Надо выбрать из flds_names все строки, а у меня выберает только по условию flds_data.fref_id=flds_names.id, как поставить условие? Или надо черз JOIN делать, но как, не могу никак понять. Если надо, таблички приведу, хотя вроде понятно.
PM MAIL   Вверх
LSD
Дата 8.10.2006, 18:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 24
Всего: 538



Цитата(alexey9 @  8.10.2006,  18:36 Найти цитируемый пост)
Надо выбрать из flds_names все строки, а у меня выберает только по условию flds_data.fref_id=flds_names.id, как поставить условие? Или надо черз JOIN делать, но как, не могу никак понять. Если надо, таблички приведу, хотя вроде понятно.

Да, надо через JOIN. Как именно зависит от того какие строки нужны на выходе. Что-то наподобие:
Код
SELECT 
  data.id AS data_id, 
  data.parent_id AS data_parent_id, 
  data.ref_id, 
  data.data_ref,
  flds_names.order_id,
  flds_data.id,
  flds_data.pref_id,
  flds_data.ref,
  flds_data.data_ru,
  flds_names.id AS fn_id,
  flds_names.name_ru
FROM
  flds_names
  LEFT JOIN flds_data ON flds_data.fref_id = flds_names.id
  LEFT JOIN data ON flds_data.ref = data.id
WHERE
  flds_data.pref_id <> 255 AND
  data.id=$curPosition AND
  data.parent_id=$curParentID
ORDER BY
   flds_names.order_id



--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
alexey9
Дата 8.10.2006, 18:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 4.10.2006

Репутация: нет
Всего: нет



Грубо говоря нужно все то что выбирается сейчас + строки из flds_names где flds_data.fref_id <> flds_names.id, ко всему прочему flds_data.data_ru должны быть пустые когда flds_data.fref_id <> flds_names.id. Как-то криво описал, если не понятно попробую еще.
p.s. выборка при этом идет еще и из остальных таблиц (data, flds_data, flds_names)

Это сообщение отредактировал(а) alexey9 - 8.10.2006, 18:12
PM MAIL   Вверх
boevik
Дата 8.10.2006, 18:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1452
Регистрация: 31.5.2004
Где: Израиль

Репутация: 6
Всего: 35



в этом случае LEFT JOIN не поможет, так как есть условия на поля из таблиц flds_data и data.
Поэтому, весь запрос отрабатывет как inner join.

Попробуй ещё раз описать, что надо получить.



--------------------
Никогда не говори никогда
PM MAIL WWW   Вверх
alexey9
Дата 8.10.2006, 20:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 4.10.2006

Репутация: нет
Всего: нет



Такс. 
Есть 3 таблицы: data, flds_names, flds_data

в data: id записи, ссылка на поле flds_data (int8), parent_id (уровень влож.).

в flds_data: ссылка на data (просто id вставленной записи в data (короче то же что и data.id)), ссылка на flds_names.id и data_ru (varchar(255))

в flds_names: id, name_ru (varchar(255))

смысл:
в flds_names есть список своийств (varchar(255)) например: "цвет", "вес", "страна", "тип", "высота" и.т.д.
в data есть запись, в flds_data значение свойств (varchar (255)) например: "синий", "россия", "12кг"

flds_data.fref_id это id строки в flds_names, flds_data.data_ru - данные.
пример:
data:
id: 132
...
id: 239
...
flds_names:
id: 1
name_ru: Вес
id: 2
name_ru: Цвет
flds_data:
id: 2003
ref_id: 132
fref_id: 1
data_ru: 12кг
id: 2004
ref: 132
fref_id: 2
data_ru: Синий

id: 18433
ref: 239
fref_id: 2
data_ru: Красный

выбираем все в одном запросе получаем что типа:
id, ... , parent_id, name_ru, data_ru
132   ....  0               Цвет        Синий
132  .....  0               Вес           12кг
239   ..... 0               Цвет         Красный
239   ....   0              Вес           NULL
Последняя строка не выбирается, т.к. в flds_data нет записи, а мне ее нужно выбрать( причем с NULL или "" в data_ru, если записи небыло)

Примерно так вот. Многое упустил, но смысл понятен, parent_id и прочий "довесок" думаю можно пока опустить.
PM MAIL   Вверх
boevik
Дата 8.10.2006, 20:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1452
Регистрация: 31.5.2004
Где: Израиль

Репутация: 6
Всего: 35



Значит между таблицами data и flds_names нужен cross join, а между flds_names и flds_data left join.
Попробуй следующую конструкцию
Код

SELECT 
  *
FROM
  flds_names
  CROSS JOIN flds_data
  LEFT JOIN data ON flds_data.ref = data.id


Кстати, какая БД?


--------------------
Никогда не говори никогда
PM MAIL WWW   Вверх
alexey9
Дата 8.10.2006, 20:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 4.10.2006

Репутация: нет
Всего: нет



mysql/postgreeSQL
Т.Е. работать и там и там будет.

Добавлено @ 20:32 
А можно по подробнее про CROSS JOIN, что-бы понимать что делаю.?

Добавлено @ 20:36 
К тому же он так не будет соблюдать условие flds_names.id = flds_data.fref_id и все перемешается - Country=Blue, Country=Russia, Color=12 etc
PM MAIL   Вверх
boevik
Дата 8.10.2006, 20:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1452
Регистрация: 31.5.2004
Где: Израиль

Репутация: 6
Всего: 35



В селекте я напутал с порядком таблиц:
Код

SELECT 
  *
FROM
  data а
  CROSS JOIN flds_names b
  LEFT JOIN flds_data c ON b.id = c.ref_id

CROSS JOIN - соединяет все записи из двух таблиц без какого либо условия.


--------------------
Никогда не говори никогда
PM MAIL WWW   Вверх
alexey9
Дата 8.10.2006, 21:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 4.10.2006

Репутация: нет
Всего: нет



не. чего-то не то... он теперь не все записи выдает. Странная хрень.
PM MAIL   Вверх
alexey9
Дата 9.10.2006, 02:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 4.10.2006

Репутация: нет
Всего: нет



boevik, спасибо за CROSS JOIN, но он оказался не нужен. Как-то вот-так все решил:

Код

SELECT
  data.id AS data_id,
  data.parent_id AS data_parent_id,
  data.ref_id,
  data.data_ref,
  flds_names.order_id,
  flds_data.id,
  flds_data.pref_id,
  flds_data.ref,
  flds_data.data_ru,
  flds_names.id AS fn_id,
  flds_names.name_ru
FROM
  data,
  flds_data
    RIGHT JOIN
        flds_names
        ON
        flds_data.fref_id = flds_names.id AND
        flds_data.pref_id <> 255 AND
        flds_data.ref = data.id
WHERE
  data.id=2023 AND
  data.parent_id=1
ORDER BY
  flds_names.order_id


PM MAIL   Вверх
boevik
Дата 9.10.2006, 09:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1452
Регистрация: 31.5.2004
Где: Израиль

Репутация: 6
Всего: 35



Цитата(alexey9 @  9.10.2006,  02:32 Найти цитируемый пост)
FROM
  data,
  flds_data

Это и есть не явное ипользование cross join

Сегодня утро и ещё раз просмотрев таблицы, нашел что забыл одно условие
Так выглядит исправленный запрос
Код

SELECT *
FROM data 
  CROSS JOIN flds_names b
  LEFT JOIN flds_data c ON b.id = c.fref_id and data.id =c.ref_id


Но если добавить условие flds_data.pref_id <> 255, то исчезнет 
Цитата

239   ....   0              Вес           NULL
, по той причине, что описал выше.




--------------------
Никогда не говори никогда
PM MAIL WWW   Вверх
alexey9
Дата 9.10.2006, 09:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 4.10.2006

Репутация: нет
Всего: нет



ok. В любом случае спасибо smile
PM MAIL   Вверх
alexey9
Дата 12.10.2006, 08:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 4.10.2006

Репутация: нет
Всего: нет



Еще проблемка вот, голову сломал, реально ли вообще? Нужно ограничить выборку
Код
...
    LEFT JOIN
    attachments ON attachments.ref = data.id
...

так, что бы выбиралась только 1 запись из attachments. Ниже кину результаты выборки (jpg) запроса, что бы понять примерно что к чему.

Код

SELECT
  data.id AS data_id,
  data.parent_id AS data_parent_id,
  data.ref_id,
  data.data_ref,
  flds_names.order_id,
  flds_data.id,
  flds_data.pref_id,
  flds_data.ref,
  flds_data.data_ru,
  flds_names.id AS fn_id,
  flds_names.name_ru,
  attachments.ref,
  attachments.attdata

FROM
  data,
  flds_data

    RIGHT JOIN
        flds_names
        ON
        flds_data.fref_id = flds_names.id AND
        flds_data.ref = data.id

    LEFT JOIN
    attachments ON attachments.ref = data.id

WHERE
  flds_names.type = 255 AND
  data.parent_id=1

ORDER BY
 id


user posted image

Это сообщение отредактировал(а) alexey9 - 12.10.2006, 08:41
PM MAIL   Вверх
boevik
Дата 12.10.2006, 08:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1452
Регистрация: 31.5.2004
Где: Израиль

Репутация: 6
Всего: 35



Примерно так:
Код

SELECT
  data.id AS data_id,
  data.parent_id AS data_parent_id,
  data.ref_id,
  data.data_ref,
  flds_names.order_id,
  flds_data.id,
  flds_data.pref_id,
  flds_data.ref,
  flds_data.data_ru,
  flds_names.id AS fn_id,
  flds_names.name_ru,
  attachments.ref,
  attachments.attdata
FROM
  data,
  flds_data
    RIGHT JOIN
        flds_names
        ON
        flds_data.fref_id = flds_names.id AND
        flds_data.ref = data.id
    LEFT JOIN
    attachments ON attachments.ref = data.id
    and attdata = (select top 1 attdata from attachments i where i.ref = data.id)   -- select only one attdata 
WHERE
  flds_names.type = 255 AND
  data.parent_id=1
ORDER BY
 id



--------------------
Никогда не говори никогда
PM MAIL WWW   Вверх
alexey9
Дата 12.10.2006, 11:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 4.10.2006

Репутация: нет
Всего: нет



Круто, спасибо. Только он на не top 1 почему-то ругался, так и не понял почему. Временно поставил LIMIT 0,1. 
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Общие вопросы по базам данных"
LSD
Zloxa

Данный форум предназначен для обсуждения вопросов о базах данных не попадающих под тематику других форумов:

  • вопросам по СУБД для которых нет отдельных подфорумов
  • вопросам которые затрагивают несколько разных СУБД (например проблема выбора)
  • инструменты для работы с СУБД
  • вопросы проектирования БД
  • теоретически вопросы о СУБД

Данный форум не предназначен для:

  • вопросов о поиске разлиных БД (если не понимаете чем БД отличается от СУБД то: а) вам не сюда; б) Google в помощь)
  • обсуждения проблем с доступом к СУБД из различных ЯП (для этого есть соответсвующие форумы по каждому ЯП)
  • обсуждения проблем с написание SQL запросов, для этого есть форум Составление SQL-запросов
  • просьб о написании курсовой, реферата и т.п., для этого есть Центр помощи или фриланс биржа
  • объявлений о найме специалистов, для этого есть раздел Объявления о найме специалистов

Если вы не соблюдаете эти правила, не удивляйтесь потом не найдя свою тему/сообщение. ;)


Полезные советы:

При написании сообщения постарайтесь дать теме максимально понятное название. В теме максимально подробно опишите проблему. Если применимо укажите: название базы данных и версии (MySQL 4.1, MS SQL Server 2000 и т.п.); используемых язык программирования; способа доступа (ADO, BDE и т.д.); сообщения об ошибках.

Для вставки кода используйте теги [code=sql] [/code].

Литературу по базам данных можно поискать здесь.

Действия модераторов можно обсудить здесь.


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, LSD, Zloxa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | СУБД, общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1015 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.