За последние 24 часа нас посетили 17615 программистов и 1617 роботов. Сейчас ищут 2002 программиста ...

помогите с запросом из нескольких таблиц

Тема в разделе "MySQL", создана пользователем Koc, 26 июл 2008.

  1. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    province
    id|title
    01|aaa
    02|aab
    03|aac

    city
    id|province_id|title
    01|000000001|bbba
    02|000000002|bbbb
    03|000000002|bbbc

    table
    id|city_id|title
    01|00001|ccca
    02|00001|cccb
    03|00002|cccc
    04|00002|cccd
    05|00003|ccce

    нужно выбрать из `table` записи, входящие в province с id=02

    результат должен быть:
    03|00002|cccc
    04|00002|cccd
    05|00003|ccce
     
  2. Ti

    Ti Активный пользователь

    С нами с:
    3 июл 2006
    Сообщения:
    2.378
    Симпатии:
    1
    Адрес:
    d1.ru, Екатеринбург
    [sql]SELECT table.* FROM table, city WHERE city_id = city.id AND province_id = 2[/sql]
     
  3. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    спасибо
     
  4. DarkElf

    DarkElf Активный пользователь

    С нами с:
    22 окт 2006
    Сообщения:
    1.632
    Симпатии:
    0
    имхо:

    [sql]SELECT `table`.`*` FROM `table` LEFT JOIN `city` ON `table`.`city_id` = `city`.`id` AND `city`.`province_id` = 2[/sql]

    и не забудь индекс на поле `table`.`city_id`.
     
  5. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    я тоже думал, что без join'а не обойтись. Не знаю, что это за зверь такой, но знаю, что лучше с ним).

    А какой именно индекс ставить? По id у меня везде стоит уникальный. А на city_id,province_id какой ставить?
     
  6. Sergey89

    Sergey89 Активный пользователь

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    Зачем LEFT JOIN, если для каждой записи указана провинция?
     
  7. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    а теперь посложнее.
    есть 4 таблицы:

    tt_attribute
    id|tid|title

    tid указывает какого типа атрибут. 1 - text, 2 - textarea, 3 - boolean

    tt_at_text
    id|value_default

    tt_at_textarea
    id|value_default

    tt_at_boolean
    id|value_default

    в зависимости от значения tid нужно брать value_default из определенной таблицы.

    Сейчас сделано так. Но работает некорректно
    [sql]
    SELECT
    tt_attribute.id, tt_attribute.tid, tt_attribute.title,
    tt_at_text.value_default,
    tt_at_textarea.value_default,
    tt_at_boolean.value_default
    FROM
    tt_attribute, tt_at_text, tt_at_textarea, tt_at_boolean
    WHERE
    tt_attribute.id IN (некое множество) AND
    (tt_at_text.id=tt_attribute.id OR tt_at_textarea.id=tt_attribute.id OR tt_at_boolean.id=tt_attribute.id)
    [/sql]

    чую, мне сюда за case, но как именно? Нид хелп.

    [sql]SELECT
    tt_attribute.id, tt_attribute.tid, tt_attribute.title
    CASE tt_attribute.tid
    WHEN 1 THEN
    SELECT tt_at_text.value_default FROM tt_at_text WHERE tt_at_text.id=tt_attribute.id
    WHEN 2 THEN
    SELECT tt_at_textarea.value_default FROM tt_at_textarea WHERE tt_at_textarea.id=tt_attribute.id
    WHEN 3 THEN
    SELECT tt_at_boolean.value_default FROM tt_at_boolean WHERE tt_at_boolean.id=tt_attribute.id
    END CASE
    FROM
    tt_attribute
    WHERE
    tt_attribute.id IN (%s)[/sql]
    не катит
     
  8. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    можно делать дополнительные запросы. Тогда на каждое уникальное значение tid будет по +1 запрос
     
  9. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    Koc
    А объединить три последние таблицы в одну была не судьба? id,text_default,textarea_default,boolean_default...
    Такую экзотику надо решать средствами PHP, а не мускула.
     
  10. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    объединять в одну таблицу нельзя. Это только значения по умолчанию. А потом будут заполненные значения.

    tt_at_text_v
    id|товар_id|value

    tt_at_textarea
    id|товар_id|value

    и как тогда делать?
    tt_at_v
    id|товар_id|value_text|value_textarea|...|
     
  11. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    Koc
    Почему нельзя?
     
  12. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    нуу.. Будет куча незаполненных полей. На каждый товар до 70 атрибутов может быть

    id|tid|value_text|value_textarea|value_boolean|value_select|value_multiselect
    1
    2
    ...
    70
    и в этих 70 строках по 4 столбца будут иметь значение NULL.

    + далее будут выпадающий список и множественный выбор. Как их сохранять?
     
  13. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    Koc
    Значения NULL физически не занимают места нисколько. Мускул хранит только значения для не-NULL полей, а чтобы не попутать что где - маленькую битовую масочку для каждой записи :)
    Так что на этом экономить не стоит. Лучше на запросах сэкономить.
     
  14. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    спасибо за добрый совет. Сначала попробую так как делаю сейчас (+3 запроса). Так же сделано в Мадженто. Будет тормозить - переделаю.

    А если мы делаем многоязычную версию магазина? и кол-во языков может меняться?
     
  15. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    Koc
    Я в таких случаях храню ру и ен поля рядом в таблице, типа titleru и titleen.
    Вообще предпочитаю по максимуму "растягивать" таблицы вместо того, чтобы увеличивать количество записей. Проще работать с одной строкой, чем с выборкой из N строк, в которой намешаны и разные записи (товары), и разные атрибуты одного товара. Хотя, конечно, все зависит от задачи...
     
  16. Vladson

    Vladson Старожил

    С нами с:
    4 фев 2006
    Сообщения:
    4.040
    Симпатии:
    26
    Адрес:
    Estonia, Tallinn
    В случае с двуязычным сайтом да, но в случае с постоянно расширяемым сайтом проще иметь N строк
     
  17. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    у меня опять проблемы с SQL.
    Таблица1
    Код (Text):
    1. id|name
    2.  1|vasya
    Таблица2
    Код (Text):
    1. id|uid|title
    2. 1 |  1|aaa
    3. 2 |  3|bbb
    4. 3 |  1|ccc
    нужно выбрать 1 строку по id из Т1 и кол-во строк из Т2, у которых uid=T1.id. Я сейчас это делаю двумя запросами, можно одним. Я знаю, как это сделать чрез UNION, но может есть более элегантный вариант?
     
  18. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Коорелированный запрос:
    [sql]
    SELECT `name`, COUNT(SELECT * FROM `tbl2` WHERE `tbl2`.`uid`=`tbl1`.`id`) FROM `tbl1`
    [/sql]
     
  19. Goryn

    Goryn Активный пользователь

    С нами с:
    4 апр 2006
    Сообщения:
    398
    Симпатии:
    0
    Адрес:
    Ярославль
    Кос
    Не в обиду, ты глумишься над участниками форума или тупишь по полной? :evil:
     
  20. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    Kreker
    благодарствую

    Goryn
    я - не тролль. Просто у меня в данный период времени нет времени на то, что б заняться изучением SQL на должном уровне. Знающий человек потратит минуту времени, на то, что б написать ответ на форуме, а пока я напишу такой запрос, ооо. SQl - это мое больное место.

    Я думал, через JOIN нужно (
     
  21. Goryn

    Goryn Активный пользователь

    С нами с:
    4 апр 2006
    Сообщения:
    398
    Симпатии:
    0
    Адрес:
    Ярославль
    Если предполагать мультиплатформенную систему от всяких LEFT JOIN я бы отказался и ограничился бы
    Where
    ....
    Group
    ....
    Having
    ....
    что поддерживается везде. :D Если не прав, расскажите где.
     
  22. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    Добавить в таблицу т1 поле "кол-во чего-то там" и при добавлении/удалении в т2 делать update основной таблицы (либо тригерами). Так делают все нормальные люди.
     
  23. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    Psih так не интересно. Я когда-то раньше так делал, но потом чего-то решил, что данные в Т2 могут каким-то чудесным образом меняться мимо системы, и тогда у нас будет неверная инфа о кол-ве в Т1.

    а вот из триггеры? я знаю, что это элементы памяти в схемах. А что они в таблицах означают.
     
  24. Frozen

    Frozen Активный пользователь

    С нами с:
    20 окт 2008
    Сообщения:
    540
    Симпатии:
    0
    Адрес:
    Москва
  25. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    опять я. БД - не мой конек
    Есть такая структура таблиц
    [sql]CREATE TABLE `orders` (
    `id` INTEGER NOT NULL AUTO_INCREMENT ,
    PRIMARY KEY (`id`)
    ) COMMENT 'Заказы';

    CREATE TABLE `orders_goods` (
    `oid` INTEGER NOT NULL COMMENT 'связь с заказами' ,
    `gid` INTEGER NOT NULL COMMENT 'связь с товаром' ,
    `quantity` INTEGER NOT NULL COMMENT 'количество товара' ,
    `price` DECIMAL NOT NULL COMMENT 'Цена' ,
    ) COMMENT 'товары заказов';
    [/sql]
    Нужно вывести список заказов в формате
    id|общая сумма,
    где общая сумма - это сумма произведения price на quantity по каждому oid.
    то есть у нас по сути связь один ко многим (один заказ и много товаров на него).

    Помогите пожалуйста.