6
January
2006

Операторы Inner Join и Outer (left, right, full) Join в SQL (Oracle)

Posted in: Базы данных, SQL, Oracle |

Ключевое слово join в SQL используется при построении select выражений. ?нструкция Join позволяет объединить колонки из нескольких таблиц в одну. Объединение происходит временное и целостность таблиц не нару?ается. Существует три типа join-выражений:

  • inner join;
  • outer join;
  • cross join;

В свою очередь, outer join может быть left, right и full (слово outer обычно опускается).
В качестве примера (DBMS Oracle) создадим две простые таблицы и сконструируем для них SQL-выражения с использованием join.

В первой таблице будет хранится ID пользователя и его nick-name, а во второй - ID ресурса, имя ресурса и ID пользователя, который может этот ресурс администрировать.

create table t_users (
t_id number(11, 0),
t_nick varchar(16),
primary key (t_id) )

create table t_resources (
t_id number(11, 0),
t_name varchar(16),
t_userid number (11, 0),
primary key (t_id) )

Содержимое таблиц пусть будет таким:

T_ID  T_NICK
  1    user1
  3    user3
  4    user4 

T_ID  T_NAME  T_USERID
  1    res1     3
  2    res2     1
  3    res3     2
  5    res5     3

Конструкция join выглядит так:

... join_type join table_name on condition …

Где join_type - тип join-выражения, table_name - имя таблицы, которая присоединяется к результату, condition - условие объединения таблиц.
Кострукция join располагается сразу после select-выражения. Можно использовать несколько таких конструкций подряд для объединения соответствующего кол-ва таблиц. Логичнее всего использовать join в том случае, когда таблица имеет вне?ний ключ (foreign key).
Inner join необходим для получения только тех строк, для которых существует соответствие записей главной таблицы и присоединяемой. ?ными словами условие condition должно выполняться всегда. Пример:

select t_resources.t_name, t_users.t_nick
  from t_resources
  inner join t_users on t_users.t_id = t_resources.t_userid

Результат будет таким:

 T_NAME  T_NICK
  res2    user1
  res1    user3
  res5    user3

В случае с left join из главной таблицы будут выбраны все записи, даже если в присоединяемой таблице нет совпадений, то есть условие condition не учитывает присоединяемую (правую) таблицу. Пример:

select t_resources.t_name, t_users.t_nick
  from t_resources
  left join t_users on t_users.t_id = t_resources.t_userid

Результат выполнения запроса:

 T_NAME  T_NICK
  res1    user3
  res2    user1
  res3    (null)
  res5    user3

Результат показывает все ресурсы и их администраторов, вне зависимотсти от того есть они или нет.

Right join отображает все строки удовлетворяющие правой части условия condition, даже если они не имеют соответствия в главной (левой) таблице:

select t_resources.t_name, t_users.t_nick
  from t_resources
  right join t_users on t_users.t_id = t_resources.t_userid

А результат будет следующим:

 T_NAME  T_NICK
  res2    user1
  res1    user3
  res5    user3
  (null)  user4

Результирующая таблица показывает ресурсы и их администраторов. Если адмнистратор не задействован, эта запись тоже будет отображена. Такое может случиться, например, если ресурс был удален.

Updated (8.03.2007):
Full outer join (ключевое слово outer можно опустить) необходим для отображения всех возможных комбинаций строк из нескольких таблиц. ?ными словами, это объединение результатов left и right join.

select t_resources.t_name, t_users.t_nick
  from t_resources
  full join t_users on t_users.t_id = t_resources.t_userid

А результат будет таким:

 T_NAME  T_NICK
  res1      user3
  res2      user1
  res3      (null)
  res5      user3
 (null)     user4

Некоторые СУБД не поддерживают такую функциональность (например, MySQL), в таких случаях обычно используют объединение двух запросов:

select t_resources.t_name, t_users.t_nick
  from t_resources
  left join t_users on t_users.t_id = t_resources.t_userid
union
select t_resources.t_name, t_users.t_nick
  from t_resources
  right join t_users on t_users.t_id = t_resources.t_userid

Наконец, cross join. Этот тип join еще называют декартовым произведением (на английском - cartesian product). Настоятельно рекомендую использовать его с умом, так как время выполнения запроса с увеличением числа таблиц и строк в них растет по экспоненте.
Вот пример запроса, который аналогичен cross join:

select t_resources.t_name, t_users.t_nick
  from t_resources, t_users

Конструкция Join (в сочетании с другими SQL конструкциями, например, group by) часто встречается при программировании под базы данных. Думаю, эта статья будет вам полезна. Кстати, для проверки своих знаний в области баз данных (и в частности Oracle) рекомендую воспользоваться этим сайтом онлайн тестирования - Тесты по базам данных.

105 Comments »

RSS feed for comments on this post. TrackBack URI



wert2all
January 6, 2006 #

думаю будет полезна.. но мало рассказано.. так всё быстро… а вот как написать запрос, что бы выводились те записи с первой таблицы. которых нет во второй? ;) это тоже следует написать

January 6, 2006 #

В статье описано, как и для чего можно использовать конструкцию join. Естественно, для определенных задач и для сложных баз данных запросы будут сложнее: со вложенными запросами, с конструкциями where, group by, c ключевыми сдовами типа distinct и так далее…

Alexander
April 8, 2006 #

Как раз то, что нужно - сейчас 3 часа ночи и вот появилось легкое непонимание разниц INNER и LEFT/
(Тут еще OUTER JOINT проскакивает - буду разбираться еще).
Вы помогли _быстро_ разобраться :)

Спасибо!

StacK515
September 3, 2006 #

Отлично! Как в хоро?ем справочнике: коротко и ясно. Спасибо!

CMP
September 6, 2006 #

Очень хоро?ая статья. Все четко и понятно. Молодцы.

River
November 16, 2006 #

Хоро?ая статья, помогла. Кратко и ясно. То, что нужно было для начала ;).

Rustam
November 23, 2006 #

Понятно но сли?ком уж кратко. Хотя бы ссылку на более подробную статью чтоли. Но все равно спасибо. Главное дано сравнение всех JOIN. Но не понятно что делать если объединяется одна и та же таблица под разными именами

Gribass
December 27, 2006 #

Статья действительно хоро?а. Спасибо.

ikota
February 8, 2007 #

Огромное спасибо, отличная статья. Моментально стало всё ясно.

April 9, 2007 #

? я благодарность наверное выпи?у за статейку :)

andrey
April 16, 2007 #

Спасибо. Как раз по лабе, которую щас буду делать :)

Boris
August 16, 2007 #

Хоро?ая статья. Мне на собеседовании вопрос про outer join задавали, а я толком ничего сказать не смог. Теперь вроде бы все ясно, спасибо!

Stan
August 17, 2007 #

Да статья действительно получилось хоро?ая. Она не вдаваясь в детали объясняет суть! А за подробностями можно не полениться и залезть в мануал СУБД

August 28, 2007 #

Ещё стоило бы упомянуть, что в Oracle, по крайней мере в 9i, есть определённые проблемы с ANSI-?ным синтаксисом join-ов. Хотя в документации и советуется его использовать взамен оракловых (+).
Поэтому пользоваться ANSI-синтаксисом следует с осторожностью (особенно full).
Подробности можно посмотреть на Металинке.

Alexxz
August 29, 2007 #

Хоро?ая статейка, мне понравилось. Коротко, ясно, а главное доступно… Без засирания мозга полным синтакиссом опреаторов и прочего. Очень наглядно продемонстрировано. Сам работаю с MySQL, однако было очень интересно прочитать. Спасибо.

Intruder
October 30, 2007 #

Всё хоро?о, корме одного:

В Oracle нет операции JOIN. Вне?ние соединения обеспечиваются в Oracle оператором (+) в эквисоединении.

Livon
November 7, 2007 #

Хоро?ая статья. Спасибо за простое изложение информации.
Неплохо было бы добавить чуть-чуть инфы о том когда следует пользоваться join.

StyleX
November 11, 2007 #

Боль?ое спасибо, инфа полезная! Как раз сдавать лабы по бд!

Aleksey
December 2, 2007 #

Боль?ое спасибо за такую понятную статью. очень доступно всё описано.

mishag
December 2, 2007 #

А что делает такой select:
Select …
from table1 left join table2 right join table3
on (join condition table2 - table3)
on (join condition table1 - table2)

Какие колонки должны попасть в результат?

anonymous
January 17, 2008 #

? мне статья понравилась: просто и понятно. Спасибо

Trinity
January 25, 2008 #

Great Thanks to you!

From Ubonratchathani University
will try to explain it to the students!

Vladimir
January 30, 2008 #

Спасибо, коротко и доступно о нужном )

hifishka
February 26, 2008 #

Боль?ое спасибо, очень полезная стать!

Aleksey
March 1, 2008 #

Класс….. +1

devochko
April 3, 2008 #

>>>а вот как написать запрос, что бы выводились те записи с первой таблицы. которых нет во второй?

select t_resources.t_name, t_users.t_nick
from t_resources
left join t_users
where t_users.t_nick is null
;)
а я рань?е работала с mssql, на новой работе оракл, и почему-то запросы с джоинами не выполняются, даже простей?ие, типа select t1.p1,t2.p2 from t1 left join t2 on t1.p1=t2.p2 не могу понять, в оракле другой синтаксис или вообще нет оператора join?:(

devochko
April 3, 2008 #

всем спасибо, я уже на?ла)))) это будет так:
select t1.p1,t2.p2 from t1, t2 where t1.p1=t2.p2 (+) = left join
select t1.p1,t2.p2 from t1, t2 where t1.p1(+)=t2.p2 = right join

Chuvak
April 7, 2008 #

Очень неплохая статья.

Anna
April 7, 2008 #

Спасибки, статейка полезная ))

LexSTV
April 13, 2008 #

мда, я ничего не имею против деву?ек it, но я хотел узнать, как правильно искользовать джойны, и заглянул сюда. Первый же пример вызвал у меня сомнения… Создал все в точности в оракловой базе, и в певом запросе выдет 4 записи, а не 3, как показано тут. Следовательно объяснения про inner join уже не верны, даль?е читать расхотелось…

April 18, 2008 #

Может мы о разных Ораклах говорим?

ONIX
April 18, 2008 #

Спасибо! самая суть…четко , коротко и понятно!!

belchonock
April 23, 2008 #

Спасибо, я наконец поняла как полозоваться джоином :)))

zuko
May 2, 2008 #

Целый день “гуглил” инет, искал “а вот как написать запрос, что бы выводились те записи с первой таблицы. которых нет во второй?”, где-то к обеду узнал, что мне нужен JOIN и только к полуночи инет все таки раскрыл ТАЙНУ кто такой JOIN. Огромное спасибо ва?ей статье!!!

Дима
May 11, 2008 #

может, я не прав, но, на мой взгляд, луч?е использовать подзапросы. Они и нагляднее и проще пи?утся. А этими Джойнами можно себе мозг взорвать

mart
May 22, 2008 #

2Дима:
То что проще, не обязательно быстрее.

Автору спасибо

mishag
May 26, 2008 #

Minus вместо Union выводит то из первой таблицы, чего нет во второй.

san
June 20, 2008 #

Мне вот интересно сравнить скорость двух запросов возвращающих одинаковые данные но использующие inner join и left join
?

h
July 3, 2008 #

?нтересно-сравни.

PavelK
July 4, 2008 #

в оракле поддержка join-ов появилась с 9-й версии, если мне память не изменяет.

July 9, 2008 #

LexSTV - ты видимо что-то не так делал. Я создал таблицы в точности с приведенными примерами, проверил все опубликованные запросы в MySQL, и убедился в их правильности - все результаты абсолютно сообтветствовали с опубликованными примерами.
Возможно Oracle интерпритирует данные запросы по другим правилам, в результате чего результат отличаеться, но скорее всего ты НЕ буквально воссоздал картину, показанную на примере вы?е. Поэтому “захоти” и почитай статью внимательнее, может что-то полезное для себя узнае?ь.

Автору спасибо!

alex
July 15, 2008 #

Да, статейка действительно доходчивая - доза теории и двойная доза практики :)

Спасибо.

SindBAD
July 17, 2008 #

Классно :) саое понятное из всех объяснений принципа работы JOIN, которое мне попадалось! Благодарю!

Надин
August 13, 2008 #

Оч хоро?ая статья!
Автору респект!
Ждем новых статей =)

ellokko
August 14, 2008 #

Спасибо! Очень помогло!

XeNt
August 20, 2008 #

Кратко и понятно!

Lavr
September 5, 2008 #

“wert2all January 6, 2006 # … а вот как написать запрос, что бы выводились те записи с первой таблицы. которых нет во второй? это тоже следует написать”

For you:

select t_resources.t_name, t_users.t_nick
from t_resources
right join t_users on t_users.t_id = t_resources.t_userid
where t_resources.t_name is null

А результат будет следующим:

T_NAME T_NICK
(null) user4

September 11, 2008 #

Спасибо. Теперь стало понятнее, чем именно отличаются все эти LEFT, RIGHT JOIN и т.д.

хорек
September 19, 2008 #

спасибо, статья помогла все быстро выяснить

Диня
November 12, 2008 #

Отличная статья! Все четко и по сути!

jocker1331
November 19, 2008 #

———-
Наконец, cross join. Этот тип join еще называют декартовым произведением (на английском - cartesian product). Настоятельно рекомендую использовать его с умом, так как время выполнения запроса с увеличением числа таблиц и рядков в них растет по экспоненте.
———-
может стоит открыть учебник алгебры и изучить что такое экспонента?

T
November 21, 2008 #

Спасибо. Полезная статья.

Pascal
December 1, 2008 #

спс!

Anna
December 10, 2008 #

LexSTV April 13, 2008 # мда, я ничего не имею против деву?ек it, но я хотел узнать, как правильно искользовать джойны, и заглянул сюда. Первый же пример вызвал у меня сомнения… Создал все в точности в оракловой базе, и в певом запросе выдет 4 записи, а не 3, как показано тут. Следовательно объяснения про inner join уже не верны, даль?е читать расхотелось…

Я думаю автор статьи - Константин - обидится за то, что его обозвали “деву?кой it”
а то, что ты первым делом обратил внимание на пол автора, говорит о том, что ты “ничего не имее?ь против деву?ек (it), но они все поголовно дуры”. Думаю, предвзятость идет из внутренних комплексов и проблем в личном общении

#может стоит открыть учебник алгебры и изучить что такое экспонента?
стоит. изучи.

Автору спасибо за статью!

Nizamovich
December 23, 2008 #

jocker1331…тут уже тебе ре?ать, открывать алгебру или нет…

статья очень полезна, спасибо!!!

vit
February 2, 2009 #

автору респект и уважуха

Sergey
February 11, 2009 #

ЗАДАЧА
1. Таблица GROUP (содержит значения Группа1, Группа2, Группа3)
2. Таблица STUDENT (содержит значения Петров, ?ванов, Сидоров в привязке к Группе1)
3. Таблица BALL (содержит итоговый балл: по Петрову - 82, по ?ванову - 69, по Сидорову - NULL)
НАДО вывести Группу1, всех студентов этой группы и ?тоговый балл, даже если он еще не назначен.

РЕШЕН?Е:
SELECT group.name, student.name, ball.score
from ball
RIGHT JOIN (student RIGHT JOIN group ON group.id = student.id )
ON student.id = ball.id
WHERE group.name = ‘Группа1′

March 12, 2009 #

JOIN прикольная тема

а описано все как нужно. конкретно и без слюней :)

Egor
April 9, 2009 #

2 Sergey

В скобках надо использовать LEFT JOIN.
?наче будет работать неправильно, если для студента не будет указана группа (или будет указана группа, отсутствующая в таблице GROUP):

SELECT group.name, student.name, ball.score
from ball
RIGHT JOIN (student LEFT JOIN group ON group.id = student.id )
ON student.id = ball.id
WHERE group.name = ‘Группа1′

Nuke
April 10, 2009 #

А кто знает, как сделать, чтобы вместо (null) в DataGrid выводился, например, пробел?

Luda
April 24, 2009 #

Отличная статья, спасибо!

Painerman
May 12, 2009 #

Спасибо!
А не подскажите, каким способом эти таблицы тупо склеить в одну, при условии уникальности ID и совпадения названий полей чтобы делать выборку уже оттуда?
T_ID T_NICK
1 user1
3 user3
4 user4
6 res1
7 res2
8 res3
5 res5

SELECT `T_ID` FROM t_users+t_resources WHERE `T_NICK`=’res5′

??? Спасибо!

SHAMo
May 21, 2009 #

Хоро?ая статья… давно хотел разобраться с этими “джоинами” ;)
Спасибо!

alsodeep
May 24, 2009 #

Спасибо, помогло быстро разобраться.

urihivoo
June 5, 2009 #

Честно говоря пытаясь на собственных таблицах создать select с join’ом сначала запутался, но потом разобрался почему:
потому что в самом начале статьи я бы переписал:

Конструкция join выглядит так:

… join_type join table_name on condition …”
на:

Конструкция join выглядит так:

…table1_name join_type join table2_name on condition …”

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

tvv1
June 11, 2009 #

полностью все 100% описано понятно и ясно сходу.
теория + примеры.
спс.

ap
June 17, 2009 #

Нормальная статья, только слово “рядки” насме?ило сильно. Правильно “ряды”, конечно.

krasovcheg
June 23, 2009 #

Спасибо за статью, ре?ил просто освежить знания и наткнулся на вас.

Кайрат Юсупов
June 24, 2009 #

Немного запутано про левые и правые таблицы.
В целом все понятно. Спасибо.

June 27, 2009 #

2 ap: спасибо, исправил. Это я с украинским языком спутал

rus92
August 13, 2009 #

А кто знает, как сделать, чтобы вместо (null) в DataGrid выводился, например, пробел?

nvl(,)

выглядит так
select nvl(a.name,’нет имени’) from students a

хммм
September 10, 2009 #

Если добавить пару картинок, как например тут То по моему будет более наглядно.

А так всё мило :)

Юрий
September 18, 2009 #

Отличная статья! Спасибо очень быстро разобрался с Full Join. Как раз то что нужно было!

MaryG
November 25, 2009 #

wert2all как раз LEFT JOIN и отвечает на Ва? вопрос: все записи с первой таблицы

sergey_mp
December 1, 2009 #

не вижу смысла вообще использовать inner join
использую Oracle SQL 10 лет и мне удобнее
и нагляднее написать (особенно если много полей
в условии where)
select t_resources.t_name, t_users.t_nick
from t_resources, t_users
where t_users.t_id = t_resources.t_userid

чем

select t_resources.t_name, t_users.t_nick
from t_resources
inner join t_users on t_users.t_id = t_resources.t_userid
Спра?иваю у программиста на новой работе- почему ты используе?ь inner join вместо простого сравнения полей , отвечает меня так научили

December 2, 2009 #

Хоро?ая статья, вот только искал описание по NATURAL JOIN, я себе представляю как работает, но хотелось бы точно)
Пример:
SELECT E.employee_id, E.last_name, department_id, D.department_name
FROM employees E
NATURAL JOIN
departments D
WHERE department_id = 30;

Если я правильно понял, то идет пересение по ключам (priary и foreign key))

ЧайникПолный
December 15, 2009 #

Спасибо, прекрасная статья.

Vitalik
January 5, 2010 #

Наконец то я понял, как работают разные Join … спасибо за краткое и понятное обьяснение

Programator
January 19, 2010 #

Работаю с PL/SQL-Developer уже боль?е пол-года, несколько раз пробовал понять этот join, и на этом примере токо уразумел (опробовал, все норм). Спасибо автору.

debuger
February 25, 2010 #

Статейка классная ибо автор воздержался блеснуть умом и доходчиво рассказал по сути!
Спасибо!

Лю?а
February 27, 2010 #

skAmZ,
natural join сочленяет по столбцам с одинаковыми именами (обычно по одному столбцу имена совпадают (в боль?инстве случаев там, где и хоче?ь сочленить), но могут несколько совпасть, тогда по ним сочленяется (ON(Т1.с1=Т2.c1)AND(Т1.с2=Т2.c2)) хотя корректней писать (ON(Т1.с1, Т1.с2)=(Т2.с1, Т2.с2)) )
также вместо ON Т1.с1=Т2.c1 можно писать USING(c1)

July
March 19, 2010 #

Отличная статья помогла разобраться с join. Спасибо !
2 Sergey
Спасибо! Ва? пост помог ре?ить мою задачу, используя вложенные join.

dervish
April 9, 2010 #

to Nuke:
А кто знает, как сделать, чтобы вместо (null) в DataGrid выводился, например, пробел?

COL[UMN]имя_столбца NULL “то, что хоче?ь
вставить вместо NULL”;

Удалить: CLEAR COLUMN

dervish
April 9, 2010 #

также:
SELECT tr.t_name, tu.t_nick
FROM t_resources tr
FULL OUTER JOIN t_users tu
ON tu.t_id = tr.t_userid;

Результат:
T_NAME T_NICK
res2 user1
res5 user3
res1 user3
res3
user4

dervish
April 9, 2010 #

Насчет FULLa - незаметил, sorry.

dervish
April 10, 2010 #

2Rustam:
Но не понятно что делать если объединяется одна и та же таблица под разными именами

SELECT p.t_name, g.t_name
FROM t_resources g, t_resources p
WHERE g.t_id = p.t_userid;

April 13, 2010 #

[…] » Операторы Inner Join и Outer left, right, full Join в SQL Oracle. […]

Prk
May 7, 2010 #

Четко, ясно и понятно. А то когда только начал изучать SQL про join было написано настолько муторно что просто махнул на них рукой, да и особой необходимости в них не было

jamland
May 9, 2010 #

спасиба!!

staS
June 20, 2010 #

Как обьединить несколько left join в delphi?

bt
June 28, 2010 #

Блин, спасибо, огромное. А то в поисковике голимые цитаты из официального мануала, где ужасно дуратские примеры :) А так сразу всё встало на свои места.

June 28, 2010 #

Рыспэкт! Разобрался в 2 минуты!

DM
June 30, 2010 #

Жаль в оракле старый синтаксис, ansi join там только начинает приживаться в новых версиях, например в materialized views при автообновлении он неподдерживается, а сам ansi join довольно неплохой оператор, позволяет избежать мусора (ненужных столбцов) в select.
Кстати, вопрос про старый оракловский синтаксис - если связаный подзапрос (во where) имеет join-связь между несколькими таблицами, как тогда построить запрос? Если используем старый синтаксис, то в select должны перечислить все столбцы, а подзапрос во where должен вернуть одно единственное значение, соответственно поверх подзапроса ставим select (count, max, min) одного столбца, но тогда теряется связь с главным запросом, так как в оракле область видимости подзапроса только на 1 уровень вверх. Тупик?
С новым ansi join сделать подобный запрос не составит труда, так как не нужно всю кучу столбцов извлекать в select.

Виталий
July 19, 2010 #

Спасибо огромное ! Ваша статья помогла и выручила ;)

July 23, 2010 #

Норм статья, по ней понял что такое left join

Єс
July 28, 2010 #

Файно розписано. Дзенькую.אַ דאַנק Köszönöm

Артём
August 5, 2010 #

Спасибо за статью! Прекрасные примеры быстро помогли вспомнить не так давно забытое)

YULIKA
December 13, 2010 #

ЕСЛИ ЕСТЬ ТАБЛИЦЫ СТРАНЫ,ДЕН.ЕД.,КОНТИНЕНТЫ,ЯЗЫК И НУЖНО СОЗДАТЬ РЕЗУЛЬТАТИРУЮЩУЮ ТАБЛИЦУ СТРАНЫ1,ЧТОБЫ ДАННЫЕ ИЗ КАЖДОЙ ТАБЛИЦЫ БЫЛИ В НЕЙ??

orrigami
February 16, 2011 #

Хорошая статья. Действительно, все коротко и по делу. Сразу все стало понятно.

orlando
March 13, 2011 #

А как соединить 2 разные таблицы не связанные друг с другом. Просто сделать чтобы выводились 2 таблицы вместе.

bors
March 29, 2011 #

Доброго времени суток всем.
Такой вопрос. Как получить по INNER JOIN лишь первое совпадение? Т. е. если несколько подходящих записей во второй таблице, присоединить только первый по порядку.

Raf
April 8, 2011 #

Спасибо за статью. все очень кратко и понятно написано. никакой воды. мало нынче такого. 5мин на этой страничке и я свободно строю запросы такого типа. ещё раз спасибо!!!!

PIvas
April 13, 2011 #

Спасибо, помогло разобраться!

Oracle
May 28, 2011 #

Хуйня полное!!!!!!!!!!!!!!!!!!!!!
Нихуя не помогло!!!!!!!!!!!!!!!!!!!!!!!!!!!
Какой-то пиздабол писал!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

smith
August 30, 2011 #

Статья гавно, написана ёбань

Leave a comment

XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong> <pre>