Гарна книга по SQL
Чи не могли би порадити гарну книгу по SQL: щоб отримати гарну базу в розумінні безпосередньо SQL і окрім того розумінням роботи із базами даних. Зазадалегідь дякую!
Чи не могли би порадити гарну книгу по SQL: щоб отримати гарну базу в розумінні безпосередньо SQL і окрім того розумінням роботи із базами даних. Зазадалегідь дякую!
left join’ить по rownum() ?
PS stackoverflow было бы эффективнее
PPS в идеале было бы сделать union all вместо join’a. потому что даже если получится одним запросом — не факт, шо разнотипные данные будут в одинаковом количестве. и лишний код по обработке строк будет тем еще подарком.
ВООБЩЕ! ненавижу когда функционал джоина имплементят через юнион
назначение JOIN — собирать данные связанных сущностей, а не работать генератором комбинаций.
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 Сборник рецептов , 2009Коментар порушує правила спільноти і видалений модераторами.
Бен Форта. Освой самостоятельно язык запросов SQL / Пер. с англ. —
Подскажите пожалуйста а где можно скачать оригинал, (не хотелось бы перевод читать поскольку там есть неточности).
-
тоді зустрічне питання, який діалект найкращий, якщо можна такий визначити...наприклад за уживанністю:)
Дякую! Це я так розумію щодо введення в системи баз даних, а як щодо гарної літератури по SQL?
36 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів