SQLinfo.ru - Все о MySQL Webew.ru: теория и практика веб-технологий

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 01.10.2009 11:01:06

Валет-69
Завсегдатай
Зарегистрирован: 23.05.2008
Сообщений: 37

Случайное изменение статуса (ENUM(), RAND() LIMIT (0,1))

Фамилия;    Статус
________________________
Иванов;       On
Петров;       Off
Сидоров;     Off

В базе данных содержится вышеизображённая таблица. В столбце (поле) "Статус" может находиться только одно из двух значений: "On" или "Off".
Требуется составить запрос, который бы осуществил следующие действия:
a) по  принципу случайности выбрать какую-либо строку (запись),
b) поменять значение статуса на противоположное,
c) затем, передать данную строку с новым значением статуса скрипту (на PHP) для отображения в браузере.
Думаю, что сама таблица должна быть создана следующим запросом:
"
CREATE TABLE mytabl
(name char(20) not null,

status ENUM('On', 'Off') not null ";
Предполагаю, что благодаря использованию типа данных ENUM(), для изменения значения статуса станет достаточно только команды, которая означает приказ поменять в данном месте значение на противоположное.
Возможно, будет полезно ввести столбец с нумерацией строк в первичном ключе:
"id int primary key".
Возможно, для решения задачи пригодится функция "RAND() LIMIT (0,1)".

Неактивен

 

#2 01.10.2009 12:26:59

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Случайное изменение статуса (ENUM(), RAND() LIMIT (0,1))

Не надо использовать ORDER BY RAND()
При выполнении этого запроса MySQL запишет во временную таблицу все строки исходной таблицы с новым полем, в котором будет содержаться результат выполнения функции RAND(). А потом будет сортировать в памяти эту таблицу по значениям добавочного поля.



    SELECT COUNT(*) INTO @row_count FROM mytabl;

    SET @rand_row = round(rand() * @row_count);

    SELECT id INTO @id FROM mytabl LIMIT rand_row, 1;

    UPDATE mytabl SET `status`=if(`status`='On','Off','On') WHERE id=@id;
 

Неактивен

 

#3 01.10.2009 14:50:51

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Случайное изменение статуса (ENUM(), RAND() LIMIT (0,1))

Судя по формулировке задачки — это задачка какой-нибудь практической лабы из школы smile
И, соответственно, она ни разу не практическая, а «покажите, что Вы умеете пользоваться
RAND()». Если так, то можно, конечно, сделать так, как просят:

ALTER TABLE mytabl ADD id INT KEY FIRST; -- добавить поле
SELECT * FROM mytabl ORDER BY RAND() LIMIT 1; -- выбрать данные и id
UPDATE mytabl SET status := IF(status = 'On', 'Off', 'On') WHERE id = $id; -- изменить значение

Неактивен

 

#4 05.10.2009 12:21:20

Валет-69
Завсегдатай
Зарегистрирован: 23.05.2008
Сообщений: 37

Re: Случайное изменение статуса (ENUM(), RAND() LIMIT (0,1))


    SELECT COUNT(*) INTO @row_count FROM mytabl;

    SET @rand_row = round(rand() * @row_count);

    SELECT id INTO @id FROM mytabl LIMIT rand_row, 1;

    UPDATE mytabl SET `status`=if(`status`='On','Off','On') WHERE id=@id;
 

Благодарю. Но появляетсяся вопрос.
Данный запрос сможет обработать версия "Мускула" 6.0.11 - последняя (с 22 мая 2009 г.) на текущий момент?
Версия " Мускула" на моём ПК (5.0.45-community-nt) не смогла. Очевидно, по следующей причине.
"Введенные пользователем переменные могут применяться только в составе выражений и там, где выражения допустимы. Заметим, что в область их применения в данное время не включается контекст, в котором явно требуется число, например, условие LIMIT в команде SELECT или выражение IGNORE number LINES в команде LOAD DATA."
(Ссылка: http://www.mysql.ru/docs/man/Variables.html.)
Пожалуйста, назовите версию "Мускула", для которой впервые вышеизложенное правило было отменено.

Неактивен

 

#5 05.10.2009 13:14:36

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Случайное изменение статуса (ENUM(), RAND() LIMIT (0,1))

Для этого нужно использовать подготовленные выражения. См. http://sqlinfo.ru/forum/viewtopic.php?id=363

set @query = CONCAT('SELECT id INTO @id FROM mytabl LIMIT ',@rand_row,', 1');
PREPARE zxc FROM @query;
EXECUTE zxc;

Неактивен

 

#6 07.10.2009 11:43:05

Валет-69
Завсегдатай
Зарегистрирован: 23.05.2008
Сообщений: 37

Re: Случайное изменение статуса (ENUM(), RAND() LIMIT (0,1))

Позвольте вернутся к началу темы и усложнить вышеприведённую таблицу.

Имя;                 E-mail;                           Время_регистрации_(integer, Unix)          Статус
________________________________________________________________________
Иванов;     ivan@aaa.ru;                            126546846464684                                     On
Петров;      petr@mailtest.ru;                     216546545656956                                      Off
Сидоров;   sidr@test2.ru; 02.03.1989;       544848949848423                                     Off

Требуется после пополнения таблицы сведениями - в случайном порядке поменять на противоположный статус для какой-либо одной записи и затем вывести эту запись на экран. При этом должна существовать возможность пополнять таблицу сведениями много раз и возможность выборочно удалять одну из записей.
Если смотреть на данную задачу глазами программиста высокого класса, то стоит ли прибегать к вводу поля "id" с первичным ключом и сплошной нумерации всех записей в таблице? Может быть, лучше приказать столбуцу "E-mail;" запоминать только уникальные значения и возложить на него исполнения тех же обязанностей, что мог ли бы возложить на это поле "id" с первичным ключом? Ведь по спортивным меркам секунда - это гигантская величина, и регистрация двух пользователей может произойти в одну и ту же секунду. Зато адрес электронной почты всегда уникален.
На мой взгляд, такой метод проще. Например, потому что не потребуется вводить дополнительные команды базе, чтобы после выборочного удаления какой-либо записи осуществлялось восстановление нарушенной сплошной нумерации.
Спасибо за предыдущие ответы. Жду ваших вероятных возражений и соображений.

Неактивен

 

#7 07.10.2009 12:07:10

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Случайное изменение статуса (ENUM(), RAND() LIMIT (0,1))

Не возражаю wink

У Сидорова email не валидный, проблемы, видимо, не в базе кроются smile

Неактивен

 

#8 15.10.2009 04:09:04

StigMata
Участник
Зарегистрирован: 15.10.2009
Сообщений: 3

Re: Случайное изменение статуса (ENUM(), RAND() LIMIT (0,1))

Сорр за оффтоп заранее ...

Валет-69 smile  Я даже знаю откуда это задание (ну или одно из мест откуда оно может быть)

Это тестовое задание для соискателя на должность "Веб-разработчик" одной компании

Я собственно выполнил . Только результат (ответ компании) пока не знаю...

Отредактированно StigMata (15.10.2009 04:09:43)

Неактивен

 

#9 15.10.2009 04:20:34

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Случайное изменение статуса (ENUM(), RAND() LIMIT (0,1))

Это как? Тестовое задание выполняется удаленно?

А где если не секрет? И можете привести полностью примеры? Просто любопытно.

Неактивен

 

#10 15.10.2009 04:39:58

StigMata
Участник
Зарегистрирован: 15.10.2009
Сообщений: 3

Re: Случайное изменение статуса (ENUM(), RAND() LIMIT (0,1))

smile сайт superjob.ru

Тестовое задание для соискателя на должность "Веб-разработчик"
Цель: продемонстрировать навыки владения PHP и MySQL.

Существует CSV-файл со следующими данными:

Фамилия Имя; E-mail; Дата рождения; Зарегистрирован; Статус
Иванов Иван; ivan@aaa.ru; 12.01.1974; 12.12.2007 15:41; On
Петров Петр; petr@mailtest.ru; 01.03.1969; 13.12.2007 20:41; Off
Сидоров Семен; sidr@test2.ru; 02.03.1989; 14.12.2007 5:21; Off
Пупкин Василий; pupkin@testtest.ru; 18.11.1988; 15.12.2007 15:41; On
Кузнецов Александр; smith@smith.com; 04.03.1999; 16.12.2007 3:28; On
Пушкин Александр; pas@pas.ru; 06.06.1799; 17.12.2007 15:41; Off
Лермонтов Михаил; lermontov@yyyy.ru; 03.10.1814; 18.12.2007 15:41; Off
Гоголь Николай; gogol@gggg.ru; 19.03.1809; 19.12.1999 15:41; Off


Требуется создать скрипт на языке PHP, который должен:
Создать MySQL таблицу под данную структуру файла.
Все данные из CSV-файла экспортировать в созданную таблицу.
Данные в поле "Зарегистрирован" должны храниться в формате INTEGER.
После полного экспорта данных в таблицу изменить для одной случайной записи в таблице статус на противоположный и вывести эту запись на экран. При этом данные этой записи должны выводиться в том же виде, в каком они были получены из CSV-файла.

Следует иметь в виду следующее:
Данные могут загружаться в БД неоднократно.
Данные могут быть выборочно удалены.


Решение пока не выложу по личным соображениям)))
Как ответ дадут - скину сюда (если оно кому нить нужно будет, конечно)

Неактивен

 

#11 15.10.2009 05:11:04

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Случайное изменение статуса (ENUM(), RAND() LIMIT (0,1))

StigMata написал:

Как ответ дадут - скину сюда (если оно кому нить нужно будет, конечно)

Удачи вам в поступлении.


P.S. Продолжая off. Посмотрел сейчас вакансии в своем городе, особенно порадовали "менеджер по выращиванию бройлеров" и "стоматолог-стажор". И ни одной it-шной вакансии.

Неактивен

 

#12 15.10.2009 05:19:36

StigMata
Участник
Зарегистрирован: 15.10.2009
Сообщений: 3

Re: Случайное изменение статуса (ENUM(), RAND() LIMIT (0,1))

vasya, а как же удаленка? неужели нету?

Неактивен

 

#13 15.10.2009 05:58:08

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Случайное изменение статуса (ENUM(), RAND() LIMIT (0,1))

Я целенаправленно не искал, а по ссылке "ещё вакансии в Орле" удаленных не было. Меня больше позабавило название вакансий - как менеджер может выращивать цыплят?

Неактивен

 

#14 15.10.2009 13:28:57

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Случайное изменение статуса (ENUM(), RAND() LIMIT (0,1))

Менеджер их не выращивает, он управляет их ростом: ходит там, уговаривает
выращиваться. Если не хватает еды — дает еду. Если просто ленивые — устраивает
нагоняи, лишает премии wink

Неактивен

 

#15 15.10.2009 13:46:34

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Случайное изменение статуса (ENUM(), RAND() LIMIT (0,1))

Нет, иду им должен давать оператор по выращиванию, а менеджер, наверное, следит чтобы она была в наличии.

Неактивен

 

#16 15.10.2009 13:52:01

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Случайное изменение статуса (ENUM(), RAND() LIMIT (0,1))

Зависит от уровня менеджера. Топ менеджер сам за наличием еды не следит, конечно wink

Неактивен

 

#17 21.10.2009 12:11:08

Валет-69
Завсегдатай
Зарегистрирован: 23.05.2008
Сообщений: 37

Re: Случайное изменение статуса (ENUM(), RAND() LIMIT (0,1))

1) Реализовать подсказку удалось в таком виде.


mysql_query("SELECT COUNT(*) INTO @rc FROM `$b`;");
mysql_query('SET @rr := ROUND(RAND() * @rc);');
$rr=mysql_result(mysql_query("SELECT @rr;"), 0, 0); settype($rr,"integer");
mysql_query("SELECT email INTO @email FROM `$b` LIMIT $rr, 1;");
mysql_query("UPDATE `$b` SET `status`=IF(`status`='On','Off','On') WHERE email=@email;");
 

Есть  недостаток. Через некоторое количество успешных активаций скрипта (количество успешных активаций разнится) - занчение статуса на противоположное не изменяется.
По какой причиние? Как устранить сбой?

2)Требуется проверить существование таблицы с конкретным название?
Какой способ проверки лучше (профессиональнее, экономичнее в отношении ресурсов)?

Отредактированно Валет-69 (21.10.2009 12:11:37)

Неактивен

 

#18 21.10.2009 13:57:34

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Случайное изменение статуса (ENUM(), RAND() LIMIT (0,1))

1) По таким общим данным локализовать ошибку вряд ли получится, попробуйте
включить --log и смотреть, какие запросы реально приходят. Заодно полезно
включить проверку ошибок при вызове mysql_*.

2) Если это операция одноразовая (например, установка программы), то достаточно
создавать таблицы командой типа CREATE TABLE IF NOT EXISTS. Если операция не
одноразовая, то стоит пересмотреть архитектуру программы. А вообще, конечно,
SHOW CREATE TABLE поможет.

Неактивен

 

#19 21.10.2009 13:58:34

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Случайное изменение статуса (ENUM(), RAND() LIMIT (0,1))

Валет-69 написал:

Есть  недостаток. Через некоторое количество успешных активаций скрипта (количество успешных активаций разнится) - занчение статуса на противоположное не изменяется.
По какой причиние? Как устранить сбой?

Да, это я был не внимателен.
Запись LIMIT x,y  - означает, что пропускается x строк и выбираются следующие y строк.
Переменная $rr принимает значения от 0 до кол-ва строк в таблице, соответственно, если выпадает максимальное значение, то ничего не выбирается, так как строки под номером большим чем кол-во строк в таблице не существует.

Валет-69 написал:

Реализовать подсказку удалось в таком виде.

Вы задали вопрос на форуме по MySQL, поэтому и решение я вам написал средствами MySQL. Если хотите пойти этим путем, то пишите хранимую процедуру, которую из внешнего приложения (например, php) останется лишь вызвать.
Если же вы решаете задачу на php, так и пишите на нем, а пользоваться при этом средствами MySQL, отправляя каждую команду отдельным запросом, это уже извращение как над собой, так и над сервером wink

Валет-69 написал:

2)Требуется проверить существование таблицы с конкретным название?
Какой способ проверки лучше (профессиональнее, экономичнее в отношении ресурсов)?

Зависит от задачи. Если вам нужно, например, создать новую таблицу, а в случае если таблица с таким именем уже существует, удалить старую, то

DROP TABLE IF EXISTS `имя таблицы`;
CREATE TABLE `имя таблицы` (...

В общем случае:
select table_name from information_schema.tables where table_name='имя таблицы' AND table_schema='имя базы';

В версиях до пятой
show tables like 'имя таблицы';

Неактивен

 

#20 22.10.2009 11:51:36

Валет-69
Завсегдатай
Зарегистрирован: 23.05.2008
Сообщений: 37

Re: Случайное изменение статуса (ENUM(), RAND() LIMIT (0,1))

Требуется - либо очистить таблицу, либо установить факт её отсутствия.
TRUNCATE TABLE `имя таблицы`;
Данный запрос полностью решает вышеизложенную задачу?
В данном решении есть уязвимые места?

Отредактированно Валет-69 (22.10.2009 11:52:38)

Неактивен

 

#21 22.10.2009 19:46:51

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Случайное изменение статуса (ENUM(), RAND() LIMIT (0,1))

Валет-69 написал:

Требуется - либо очистить таблицу, либо установить факт её отсутствия.

Странная постановка задачи.

Валет-69 написал:

TRUNCATE TABLE `имя таблицы`;
Данный запрос полностью решает вышеизложенную задачу?
В данном решении есть уязвимые места?

Попробуйте выполнить эту команду для несуществующий таблицыwink

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson