Ну... коль никто не пишет - предложу еще одну задачку. Не такая интересная как предыдущая - но здесь задачка немног другая - максимально упростить решение. Только что придумал условия - но прием, применяемый в данной задаче, достаточно распространенный. Вот дамп базы: Code: -- -- Структура таблицы `fruits` -- CREATE TABLE IF NOT EXISTS `fruits` ( `name` varchar(50) NOT NULL, PRIMARY KEY (`name`) ) ENGINE=InnoDB DEFAULT CHARSET=cp1251; -- -- Дамп данных таблицы `fruits` -- INSERT INTO `fruits` (`name`) VALUES ('apple'), ('banana'), ('orange'), ('pear'); Задача следующая: получить все пары значений (т.е. в результирующей выборке будет 2 столбца), подпадающие под след. условия: 1) Одного и того же фрукта в обоих столбцах быть не должно 2) Кортежи, в которых ячейки поменяны местами считаются одинаковыми. Т.е. если у нас есть ------------------ | banana | apple | ------------------ то ------------------ | apple | banana | ------------------ уже быть не должно Ждем максимально компактного решения
Да, молодец... В общем правильный подход. Только Code: SELECT * FROM `fruits` as `f1`,`fruits` as `f2` WHERE `f1`.`name`>`f2`.`name` данный код (через декартово произведение) в этом конкретном случае отработает чуточку быстрее (0.0003 сек. против 0.0008 сек). Хотя с увеличением таблицы эта разница конечно же будет незаметна, а при некоторой оптимизации скорее всего будет обратная ситуация
Помню первая задача из этой темки вызвала ажиотаж в свое время Итак, недавно свой взгляд на данную задачу опубликовал один mvp... Думаю тем кто решал данную задачку, будет интересно посмотреть: "Как объединить данные из двух столбцов в один без использования UNION и JOIN?"
Я так до конца и не понял как красиво решить задачу с компутерными кусками. Хотябы проще возьмем из моей практики. Есть 2 таблицы. В одной написаны Id | Id_Получатель | Id_Отправитель | Текст сообщения Во второй Id | Имя. Нужно на выходе получить структуру Id_сообщения | Имя 1 отправителя | Имя 2 получателя | Текст сообщения Как сделать такую выборку единым запросом?
В твоем приме ничего нетривиального нет А для таких вопросов существует спец. топик, с вопросами по sql... Так что просьба не захламлять топик =\
Давно никто ничего не выкладывал здесь. А жаль. Разминка для мозга полезна Ну что ж - выложу небольшую задачку. Она достаточно проста, но как говорится на безрыбье... В общем вы поняли =) На данную задачку меня натолкнул следующий факт: все чащи люди неправильно проектируют структуру БД, а потом страдают. Возьмем пример: Code: login | param | value -------------------------------------- Alex | City | London Alex | RegDate | 22-04-2009 Alex | Email | [email protected] Nata | City | Paris Nata | RegDate | 15-07-2009 Nata | Email | [email protected] Налицо безграмотнейшее составление структуры. Отношение не находится даже в 1НФ. И как следствие у людей начинаются большие проблемы с составлением запросов =) И начинают они плакаться в соцсетях с просьбами о помощи. Так вот - нормальную структуру, допустим, выяснили, осталось сконвертить для нее данные. Структура: Code: login | city | regdate | email Т.е. задача состоит в том, что бы из вышеприведенной таблички одним запросом получить данные в формате, приведенном выше. Дамп базы (для ленивых, что б не создавать структуру и не писать инсерты): Code: CREATE TABLE IF NOT EXISTS `tst` ( `login` varchar(20) NOT NULL DEFAULT '', `param` varchar(10) NOT NULL DEFAULT '', `value` varchar(20) DEFAULT NULL, PRIMARY KEY (`login`,`param`) ); INSERT INTO `tst` (`login`, `param`, `value`) VALUES ('Alex', 'City', 'London'), ('Alex', 'Email', '[email protected]'), ('Alex', 'RegDate', '22-04-2009'), ('Nata', 'City', 'Paris'), ('Nata', 'Email', '[email protected]'), ('Nata', 'RegDate', '15-07-2009'); Задача решается не одним способом =) Итак - разомните мозги, отложите на минутку свой "набор кавычек".
Code: mysql> SELECT t1.login, t1.value as city, t2.value as regdate, t3.value as email FROM `tst` t1 -> LEFT JOIN `tst` t2 ON t1.login = t2.login AND t2.param='regdate' -> LEFT JOIN `tst` t3 ON t1.login = t3.login AND t3.param='email' -> GROUP BY t1.login; +-------+--------+------------+-----------------+ | login | city | regdate | email | +-------+--------+------------+-----------------+ | Alex | London | 22-04-2009 | [email protected] | | Nata | Paris | 15-07-2009 | [email protected] | +-------+--------+------------+-----------------+ 2 rows in set (0,00 sec) Code: mysql> SELECT login, -> (SELECT `value` FROM `tst` WHERE `login`=t1.login AND `param`='city') as city, -> (SELECT `value` FROM `tst` WHERE `login`=t1.login AND `param`='regdate') as regdate, -> (SELECT `value` FROM `tst` WHERE `login`=t1.login AND `param`='email') as email -> FROM `tst` t1 -> GROUP BY `login`; +-------+--------+------------+-----------------+ | login | city | regdate | email | +-------+--------+------------+-----------------+ | Alex | London | 22-04-2009 | [email protected] | | Nata | Paris | 15-07-2009 | [email protected] | +-------+--------+------------+-----------------+ 2 rows in set (0,01 sec)
Итак, никто не хочет остальные методы решения для прошлой задачи придумывать - ну и ладно =) Еще одна задачка. На мой взгляд более интересная. Имеется в наличии такая вот табличка Code: -------------------------------- model | name | maker -------------------------------- 1035 | pliers | F 1103 | pestle | A 1104 | key | G 1132 | nippers | G 1273 | gavel | F 1314 | chisel | A 1402 | mortar | B 1561 | bottle | F Необходимо добавить столбец с номерами строк (т.е. номер кортежа - и собственно кортеж), в порядке возрастания модели. Пользоваться можно ТОЛЬКО средствами, предусмотренными стандартом SQL-92 (т.е. без всяких rank(), row_number() и подобных функций), а так же без временных таблиц и иже с ними. По хорошему - это один запрос (ну, возможно с коррелирующим подзапросом, но можно сделать и без него). В итоге мы должны получить примерно следующее: Code: ---------------------------------------- num | model | name | maker ---------------------------------------- 1 | 1035 | pliers | F 2 | 1103 | pestle | A ... | ... | ... | ... Ну и по традиции дамп: Code: CREATE TABLE `tst2` ( `model` INT( 3 ) NOT NULL , `name` VARCHAR( 20 ) NOT NULL , `maker` CHAR( 1 ) NOT NULL , PRIMARY KEY ( `model` ) ); INSERT INTO `tst2` VALUES ('1104','key','G'), ('1273','gavel','F'), ('1035','pliers','F'), ('1132','nippers','G'), ('1314','chisel','A'), ('1103','pestle','A'), ('1402','mortar','B'), ('1561','bottle','F')
нет, ну почему, интересно, просто на практике нафиг такое никогда не понадобиться. Лучше бы чонить жизненное, что могло бы хоть когда нибудь пригодиться.
А представь прийдется поработать со старой СУБД? В жизни всякое бывает =) Относительно недавно это не так уж и редко использовалось на практике.
[font=Consolas,monospace]<spoiler> select count(*) as num, current.* from test as current, test where current.model >= test.model group by current.model order by current.model asc </spoiler>[/font]
На этот раз проверим как у нас обстоят дела с работой со строками. Задача: есть таблица с единственным полем, в котором записаны cтроки вида Code: sdfdf_efgregehmtri_ref_WEFEW_reg_regbb На выходе нужно заменить все что находится между первым и последним символами "_" на "*". Т.е. по вышеприведенной строке должно получится такое: Code: sdfdf_**************************_regbb Вот небольшой дамп (хотя легче самим что нить набить (предварительно подумав), дабы отловить некоторые "подводные камни" и т.п.): Code: CREATE TABLE IF NOT EXISTS `tst` ( `field` varchar(40) NOT NULL ); INSERT INTO `tst` (`field`) VALUES ('aaaa_wd_regr_dew_bbbb'), ('asd_sed_fergf') Реализации для конкретных СУБД могут немного отличаться, но суть от этого не меняется. upd: естественно как всегда ответ - единственный запрос. Без рекурсий и тп. Так же никаких хп. Ну в общем вы поняли =)
хз, это, наверно, извращенный метод, но что пришло в голову =) Code: select concat_ws('_', substring_index(url, '_', 1), repeat('*', length(url) - length(substring_index(url, '_', 1)) - length(substring_index(url, '_', -1)) - 2), substring_index(url, '_', -1)) as str from t1;
В принципе ход мысли правильный... Хотя ничего особо сложного в данной задачке нет =) Но все равно молодец)