Archive for the ‘mySql’ Category

Хранение IP в MySql

Tuesday, March 18th, 2008

Для хранения IP в базе воспользуйтесь двумя функциями, INET_ATON что бы добавить

SELECT INET_ATON('127.0.0.1'), INET_ATON('127.1');
-- 2130706433, 2130706433

и INET_NTOA что бы получить

SELECT INET_NTOA(3520061480);
-- '209.207.224.40'

или выбрать промежуток

SELECT * FROM Sessions WHERE ip_address
BETWEEN INET_ATON('192.168.0.1') AND INET_ATON('192.168.0.255');

PS: поле под ip_address должно быть int

REGEXP в MySQL

Thursday, March 13th, 2008

Самое простое выражение это

SELECT 'Hello' REGEXP '^lo'; - - вернет 0
SELECT 'Hello' REGEXP 'lo$'; - - вернет 1

Но нам ведь не нужны эти шалости. Тогда код для серьезной работы

SELECT * FROM wp2_usermeta where meta_key REGEXP '^wp';

Вернет все записи где текст в колонке meta_key начинается с букв “wp”. Или где присутствует в тексте число

SELECT * FROM wp2_usermeta where meta_value Regexp '[[:digit:]]';

Перевод MySQL DATETIME в JS Date()

Monday, March 3rd, 2008

Вот такая функция

function mysqlTimeStampToDate(timestamp) {

var regex=/^([0-9]{2,4})-([0-1][0-9])-([0-3][0-9])
   (?:([0-2][0-9]):([0-5][0-9]):([0-5][0-9]))?$/;
var parts=timestamp.replace(regex,"$1 $2 $3 $4 $5 $6").split(' ');
return new Date(parts[0],parts[1],parts[2],parts[3],parts[4],parts[5]);

}

надо сказать здесь поверяется соответствие даты формату, например [0-9]{2,4} говорит о том что год может быть как 2-х так 4-х циферный, если быть уверенным, что входящая дата выглядит по всем правилам то проверку можно сделать проще

var regex=/^([0-9]{4,})-(\d\d)-(\d\d) (?:(\d\d):(\d\d):(\d\d))?$/;

MySql даты по-русски

Wednesday, February 13th, 2008

Заставим дельфина говорить по-русски, тем более что он и так умеет, только не хочет ;)
Для начала выставим русскую локаль

set lc_time_names='ru_RU';

теперь можно получать даты по русски

SELECT date_format('2008-02-10', '%W, %e %M %Y')
-- Воскресенье, 10 Февраля 2008

Варианты формата даты

%a Короткое название недели (Вск..Пнд)
%b Короткое название месяца (Феб..Мaр)
%c Месяц числом (0..12)
%D суфикс для ангийских чисел(0th, 1st, 2nd, 3rd, …)
%d День с ведущим нулём (00..31)
%e День (0..31)
%f Микросекунды (000000..999999)
%H Час с ведущим нулём, начало от нуля (00..23)
%h Час с ведущим нулём (01..12)
%I Час с ведущим нулём (01..12)
%i Минуты с ведущим нулём (00..59)
%j День в году (001..366)
%k Час, отсчет от нуля (0..23)
%l Час (1..12)
%M Month name (January..December)
%m Номер месяца с ведущем нулём (00..12)
%p AM or PM
%r Время, 12 часовой формат (hh:mm:ss и
AM or PM)
%S Секунды (00..59)
%s Секунды (00..59)
%T Время, 24 часовой формат (hh:mm:ss)
%U Неделя (00..53), первый день недели Воскресенье
%u Неделя (00..53), первый день недели Понедельник
%V Номер недели в году (01..53), где неделя начинается с Воскресенья; используется с %X
%v Номер недели в году (01..53), где неделя начинается с Понедельника; используется с %x
%W Название недели (Sunday..Saturday)
%w Номер недели
(0=Воскресенье..6=Суббота)
%X Год, 4 числа, где нелеля начинается с Воскресенья; использовать с %V
%x Год, 4 числа, где нелеля начинается с Понедельника; использовать с %v
%Y Год 4 числа
%y Год, 2 числа
%% Знак процент

Жаль, что хоть это и напоминает strftime в php, в нем нету варианта %c - preferred date and time representation for the current locale (предпочтительный вариант отображения даты)

Предыдущая и следующая строки

Monday, February 11th, 2008

Вариан первый это

SELECT * FROM topics WHERE id=($Id + 1) LIMIT 1
SELECT * FROM topics WHERE id=($Id - 1) LIMIT 1

но если не полагаться на то, что запись с id=($Id - 1) то можно написать так.

SELECT * FROM topics WHERE id > $Id ORDER BY id ASC LIMIT 1
SELECT * FROM topics WHERE id < $Id ORDER BY id DESC LIMIT 1

case в mysql

Thursday, January 31st, 2008

В таблице одна из колонок содержала в себе тип emun('Y', 'N'), которая возвращала соотвественно Y - N. А хотелось получать человеческое yes - no, для этого написал следующий запрос

SELECT id,
CASE used
WHEN 'Y' THEN 'yes' WHEN 'N' THEN 'no' else 'empty' END AS used
FROM users

К сожалению case не поддерживает выражения типа >10 для чисел, приходится использовать if.
Впрочем если подключить фантазию можно делать вот такие отчеты

SELECT
CASE count(*)
WHEN '0' THEN 'нету' ELSE Concat('найдено: ', count(*)) END
as used
FROM users Where used = 'Y'

Красивые отчеты по “итого”

Wednesday, January 30th, 2008

Раскопал неплохую штуку с применением WITH ROLLUP и IFNULL. Что делает ROLLUP, подсчитывает общую сумму выведенного результата.

mysql> select name, sum(ints)
from test_table group by name WITH ROLLUP;
+----------+-----------+
| names    | sum(ints) |
+----------+-----------+
| Igor     |        70 |
| Ira      |        10 |
| Ruslan   |        35 |
| NULL     |       115 |
+----------+-----------+

Как видно ROLLUP добавил в конец строчку, здорово но не красиво, меня например смущает NULL в первой колонке, для этих целей воспользуемся IFNULL.

mysql> select
IFNULL(name, 'All') as names, sum(ints) as sum
from test_table group by name WITH ROLLUP;
+----------+------+
| names    | sum  |
+----------+------+
| Igor     |   70 |
| Ira      |   10 |
| Ruslan   |   35 |
| All      |  115 |
+----------+------+

Новая база для нового пользователя

Thursday, January 10th, 2008

Под рутом заходим в базу
Создаем нового пользователя

CREATE USER 'username'@'localhost' IDENTIFIED BY 'userpass';

Создаем по него базу

create database dbname;

Даем новому пользоваетлю права на эту базу

grant all on dbname.* to username@localhost identified by 'userpass';

Охота на дубликаты

Thursday, December 20th, 2007

С кем такого не бывает. Вот тестовая таблица test в которой повторяются данные 

323-2

Введем код

SELECT code, count(code) as pereat
FROM test
GROUP by code HAVING ( COUNT(code) > 1 )

 
и получаем результат

323-3  

Осторожно bind_columns

Tuesday, November 13th, 2007

Вчера нарвался на довольно неприятную особенность работы с MySql у perl.

$sth1 = $dbh->prepare($sql);
$sth1->execute;
$sth3->bind_columns(\$id);
while($sth2->fetch){
...
  $sth2 = $dbh->prepare($sql2);
  $sth2->execute;
  $sth2->bind_columns(\$big, \$autor);
  $sth2->fetch;
}

Первый запрос, первый раз вернул “1″, которое подставилось в $sql2 и тогда второй запрос вернул “5″, “Мет”, но когда запрос пошел второй раз и значений равных условию не оказалось, то как думаете чему по прежнему равнялись переменные $big и $autor? по прежнему “5″, “Мет”.

Получается DBI не обнуляет переменные которым присваивает значения в случае нулевого возврата от SQL. Это надо делать самому, в ручную.