Гарна книга по SQL

Чи не могли би порадити гарну книгу по SQL: щоб отримати гарну базу в розумінні безпосередньо SQL і окрім того розумінням роботи із базами даних. Зазадалегідь дякую!

👍НравитсяПонравилось0
В избранноеВ избранном0
LinkedIn
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

left join’ить по rownum() ?
PS stackoverflow было бы эффективнее
PPS в идеале было бы сделать union all вместо join’a. потому что даже если получится одним запросом — не факт, шо разнотипные данные будут в одинаковом количестве. и лишний код по обработке строк будет тем еще подарком.

ВООБЩЕ! ненавижу когда функционал джоина имплементят через юнион

назначение JOIN — собирать данные связанных сущностей, а не работать генератором комбинаций.

стоит посмотреть в сторону CTE (Common Table Expressions)

left join ничего не даст
по rownum() ?
так как джоин нужен что бы соединить данные по определенному параметру

сначала кросс джоин и дублирование, а теперь «определенные условия» уже.
то есть, таки нормальные джоин, но логика уникализации не указана: если нечто из первой выборки совпадает с тремя элементами из второй, какую комбинацию выбрать? логика-таки есть?

не знаю, чего у вас там join по row_number не устраивает.
накидал простой запрос на тех таблицах, шо были под рукой.
джоин по row_number, который у каждого подзапроса свой, нормально уникализировал.

ну, типа такого

select *
from
(select row_number() over (order by name) as row_id, name as product_name
from products) as product
inner join (select row_number() over (order by name) as row_id, name as category_name
from categories) as category
on product.row_id = category.row_id
если добавить бизнес условие джоина как у меня в примере — то результат будет 0

а как в вашем случае должно выглядеть меню, если ваще ни одного десерта нет?
впрочем, даже так, вы можете делать LEFT JOIN по подзапросам и получать что-то типа
soup1, meal34, NULL

уточню только: если задача так в реальности и звучит, то в сеты блюда объединяют с учетом стоимости — например, минимизировать максимальную из цен(увеличив доход) или минимизировать стандартное отклонение(стабильнее — то есть, проще прогнозировать).
Или там, выделить отдельный набор для вегетарианцев.
И прочие нюансы оптимизационного характера, которые SQL гарантированно не потянет.

Но если это «гипотетическая задача для демонстрации вопроса», то ок.

тогда я бы делал генерацию клиентским кодом.
сначала с помощью union соединил бы в полотно(или оно из одной таблицы? тогда это ваще был бы простейший select из одной таблицы: select name, category ...), а потом клиентским кодом комбинировать. ну, в смысле, тут декларативным SQL намного сложнее сделать, чем императивным кодом. Это как с регулярками и проверкой корректности скобок: сложно, но долго и больно

PS и все же мне кажется странным, что абсолютный рендом устраивает.

Есть в Oracle такая штука как PIVOT. Подробнее тут (oracleplsql.ru/pivot.html) .
Еще можна self join.
Еще вот вариант по-корявее, но не требует спецфических конструкций (на случай если у Вас не оракл).
select tb1.x1,...tb1.xn, tb2.name, tb3.name
from tb_main tb1
left join some_tb tb2
on tb1.key = tb2.key
left join some_tb tb3
on tb1.key = tb3.key
where
tb2.name = ’крылышки’
and tb3.name = ’ножки’.
Это если я правильно поняла Вашу задачу.

Мне бы диаграмку табличек увидеть, а то я не до конца понимаю задачу. А не могли бы вы ею со мной поделиться если не тут, то на почту к примеру. Мне уже из принципа интересно что там да как:)

сгенерировать все комбинации, но оставить рандомно только такие, чтоб каждое блюдо встречалось не более одного раза.
и для этого использовать SQL, бо его JOIN как раз делает все комбинации.

табличка одна: список «название блюда» + "тип"(десерт/салат/первое блюдо/гарнир)

зробив аналог row_number і partition by на mysql :
select
B.row_num,
B.name as salad,
C.name as soup,
B.subregion
from
(select @gr1:= ’’, @rn1:= 0, @gr2:= ’’, @rn2:= 0) AS init
cross join
(select
IF(A.subregion <> @gr1, @rn1:=1, @rn1:=@rn1+1) as row_num,
A.name,
A.subregion,
@gr1:= A.subregion as reg1
FROM
(select ’salad1′ as name, ’region1′ as subregion
union
select ’salad2′ as name, ’region1′ as subregion
union
select ’salad3′ as name, ’region2′ as subregion ) AS A
order by A.subregion) AS B
inner join
(select
IF(A.subregion <> @gr2, @rn2:=1, @rn2:=@rn2+1) as row_num,
A.name,
A.subregion,
@gr2:= A.subregion as reg1
FROM
(select ’soup1′ as name, ’region1′ as subregion
union
select ’soup2′ as name, ’region1′ as subregion
union
select ’soup3′ as name, ’region2′ as subregion ) AS A
order by A.subregion) AS C on B.row_num = C.row_num and B.subregion = C.subregion

после изучения самого SQL есть смысл почитать эту книгу:
Рефакторинг SQL-приложений

Автор: Стефан Фаро, Паскаль Лерми

Когда прочитаете Дейта и прочую основу основ — берите

Энтони Молинаро — SQL Сборник рецептов , 2009

obuk.ru/...k-receptov.html

Microsoft SQL Server 2005. Библия пользователя
Автор: Нильсен Пол.
Год издания: 2008.
Страниц: 1232 с.

pr-lib.at.ua/..._dannykh/sql/35

Бен Форта. Освой самостоятельно язык запросов SQL / Пер. с англ. — 3-е изд. — М.: Диалектика, 2005. — 288 с.

Подскажите пожалуйста а где можно скачать оригинал, (не хотелось бы перевод читать поскольку там есть неточности).

Перевод там нормальный. Книга отличная

тоді зустрічне питання, який діалект найкращий, якщо можна такий визначити...наприклад за уживанністю:)

Дякую! Це я так розумію щодо введення в системи баз даних, а як щодо гарної літератури по SQL?

Подписаться на комментарии