if - else - elseif / else if - while

if

<?php
if ($a > $b)
echo "a больше b";
?>

else

<?php
if ($a > $b) {
echo "a больше, чем b";
} else {
echo "a НЕ больше, чем b";
}
?>

elseif / else if 

<?php
if ($a > $b) {
echo "a больше, чем b";
} elseif ($a == $b) {
echo "a равен b";
} else {
echo "a меньше, чем b";
}
?>

whileявляются простейшим видом циклов в PH

<?php
/* пример 1 */
$i = 1;
while ($i <= 10) {
echo $i++; /* выводиться будет значение переменной
$i перед её увеличением
(post-increment) */
}

/* пример 2 */
$i = 1;
while ($i <= 10):
echo $i;
$i++;
endwhile;
?>
php

PHP - ИНФОРМАЦИЯ

$GLOBALS — Ссылки на все переменные глобальной области видимости
Ассоциативный массив (array), содержащий ссылки на все переменные глобальной области видимости скрипта, определенные в данный момент. Имена переменных являются ключами массива.
Пример:
<?php
function test() {
    $foo = "local variable";
    echo '$foo in global scope: ' . $GLOBALS["foo"] . "\n";
    echo '$foo in current scope: ' . $foo . "\n";
}

$foo = "Example content";
test();
?>
$_REQUEST — Переменные HTTP-запроса
Ассоциативный массив (array), который по умолчанию содержит данные переменных $_GET, $_POST и $_COOKIE.
$_GET -- $HTTP_GET_VARS [deprecated] — GET-переменные HTTP
Ассоциативный массив параметров, переданных скрипту через URL.
$HTTP_GET_VARS содержит аналогичный набор данных, но не является суперглобальным. (Заметьте, что $HTTP_GET_VARS и $_GET являются разными переменными и обрабатываются PHP независимо друг от друга)
$_POST -- $HTTP_POST_VARS [deprecated] — HTTP POST variables
Ассоциативный массив данных, переданных скрипту через HTTP метод POST.
$HTTP_POST_VARS содержит аналогичный набор данных, но не является суперглобальным. ($HTTP_POST_VARS и $_POST являются разными переменными и обрабатываются PHP независимо друг от друга)
$_SESSION -- $HTTP_SESSION_VARS [устаревшее] — Переменные сессии
Ассоциативный массив, содержащий переменные сессии, которые доступны для текущего скрипта. Смотрите документацию по функциям сессии для получения дополнительной информации.
$HTTP_SESSION_VARS первоначально содержит ту же информацию, но она не является суперглобальной переменной. (Обратите внимание, что $HTTP_SESSION_VARS и $_SESSION являются различными переменными и в таковом качестве обрабатываются PHP).
php

Объяснение SQL объединений JOIN: LEFT/RIGHT/INNER/OUTER

Разберем пример. Имеем две таблицы: пользователи и отделы.
U) users               D) departments
id name       d_id     id  name
-- ----       ----     --  ----
1  Владимир    1       1  Сейлз
2  Антон       2       2  Поддержка
3  Александр   6       3  Финансы
4  Борис       2       4  Логистика
5  Юрий        4
SELECT u.id, u.name, d.name AS d_name
FROM users u
INNER JOIN departments d ON u.d_id = d.id
Запрос вернет объединенные данные, которые пересекаются по условию, указанному в INNER JOIN ON <..>
В нашем случае условие <таблица_пользователей>.<идентификатор_отдела> должен совпадать с <таблица_отделов>.<идентификатор>
В результате отсутствуют:
- пользователь Александр (отдел 6 - не существует)
- отдел Финансы (нет пользователей) 
id name       d_name
-- --------   ---------
1  Владимир    Сейлз
2  Антон       Поддержка
4  Борис       Поддержка
3  Юрий        Логистика

sql inner join

Внутреннее объединение INNER JOIN (синоним JOIN, ключевое слово INNER  можно опустить). 
Выбираются только совпадающие данные из объединяемых таблиц. 
 Чтобы получить данные, которые подходят по условию частично, необходимо использовать внешнее объединение - OUTER JOIN
 Такое объединение вернет данные из обеих таблиц (совпадающие по условию объединения) ПЛЮС дополнит выборку оставшимися данными из внешней таблицы, которые по условию не подходят, заполнив недостающие данные значением NULL.

sql left join

Существует два типа внешнего объединения OUTER JOIN - LEFT OUTER JOIN  и RIGHT OUTER JOIN
Работают они одинаково, разница заключается в том что LEFT - указывает что "внешней" таблицей будет находящаяся слева (в нашем примере это таблица users). 
Ключевое слово OUTER можно опустить. Запись LEFT JOIN идентична LEFT OUTER JOIN.
SELECT u.id, u.name, d.name AS d_name
FROM users u
LEFT OUTER JOIN departments d ON u.d_id = d.id
Получаем полный список пользователей и сопоставленные департаменты.
id      name          d_name
--      --------      ---------
1       Владимир      Сейлз
2       Антон         Поддержка
3       Александр     NULL
4       Борис         Поддержка
5       Юрий          Логистика
Добавив условие 
WHERE d.id IS NULL
в выборке останется только 3#Александр, так как у него не назначен департамент.

sql left outer join

RIGHT OUTER JOIN вернет полный список департаментов (правая таблица) и сопоставленных пользователей.
SELECT u.id, u.name, d.name AS d_name
FROM users u
RIGHT OUTER JOIN departments d ON u.d_id = d.id
id      name        d_name
--      --------    ---------
1       Владимир    Сейлз
2       Антон       Поддержка
4       Борис       Поддержка
NULL    NULL        Финансы
5       Юрий        Логистика
Дополнительно можно отфильтровать данные, проверяя их на NULL.
SELECT d.id, d.name
FROM users u
RIGHT OUTER JOIN departments d ON u.d_id = d.id 
WHERE u.id IS null
В нашем примере указав WHERE u.id IS null, мы выберем департаменты, в которых не числятся пользователи. (3#Финансы)

Cross/Full Join

FULL JOIN возвращает `объединение` объединений LEFT и RIGHT таблиц, комбинируя результат двух запросов.
CROSS JOIN возвращает перекрестное (декартово) объединение двух таблиц. Результатом будет выборка всех записей первой таблицы объединенная с каждой строкой второй таблицы. Важным моментом является то, что для кросса не нужно указывать условие объединения.

Дублирование строк при использовании JOIN

При использовании объединения новички часто забывают что результирующая выборка может содержать дублирующиеся данные!
Если вам нужна одна запись, делайте объединение с подзапросом
SELECT t1.*, t2.* from left_table t1 left join (select * from right_table where some_column = 1 limit 1) t2 ON t1.id =t2.join_id

Self Join

Выборка из одной и той же таблицы для нескольких условий.
Рассмотрим задачку от яндекса: 
Есть таблица товаров.
CREATE TABLE `ya_goods` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(64) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into ya_goods values (1, 'яблоки'), (2, 'яблоки') ,(3, 'груши'), (4,'яблоки'), (5, 'апельсины'), (6, 'груши');
Она содержит следующие значения.
`id`    `name`
1       Яблоки
2       Яблоки
3       Груши
4       Яблоки
5       Апельсины
6       Груши
Напишите запрос, выбирающий уникальные пары `id` товаров с одинаковыми `name`, например:
(1,2), (4,1), (2,4), (6,3)...
При решении задачи необходимо учесть, что пары (x,y) и (y,x) — одинаковы.
Решение:
SELECT g1.id id1, g2.id id2
-- CONCAT('(', LEAST(g1.id, g2.id), ',', GREATEST(g1.id, g2.id), ')') row
FROM ya_goods g1 
INNER JOIN ya_goods g2 ON g1.name = g2.name 
WHERE g1.id <> g2.id
GROUP BY LEAST(g1.id, g2.id), GREATEST(g1.id, g2.id)
ORDER BY g1.id;
 
-- или без группировки (быстрее)
 
SELECT DISTINCT CONCAT('(', LEAST(g1.id, g2.id), ',', GREATEST(g1.id, g2.id), ')') row
FROM ya_goods g1 
INNER JOIN ya_goods g2 ON g1.name = g2.name 
WHERE g1.id <> g2.id
Объединяем таблицы ya_goods по одинаковому полю `name`, группируем по уникальным idентификаторам и получаем результат.
(1,2)(1,4)(2,4)(3,6)

Множественное объединение multi join

Пригодится нам, если необходимо выбрать более одного значения из таблиц для нескольких условий.
Пример: набор вариантов (вес, объем) товаров. 
Продукты в таблице products, Варианты - таблица product_options, Значения вариантов - таблица product2options
Необходимо: фильтровать продукты по дате, и имеющимся вариантам
CREATE TABLE  `products` (
  `id` int(11),
  `title` varchar(255),
  `created_at` datetime
)
 
CREATE TABLE `product_options` (
  `id` int(11),
  `name` varchar(255)
)
 
CREATE TABLE `product2options` (
  `product_id` int(11),
  `option_id` int(11),
  `value` int(11)
)
Тестовые данные
INSERT INTO `products` (`id`, `title`, `created_at`) VALUES
        (1, 'Кружка', '2009-01-17 20:00:00'),
        (2, 'Ложка', '2009-01-18 20:00:00'),
        (3, 'Тарелка', '2009-01-19 20:00:00');
 
INSERT INTO `product_options` (`id`, `name`) VALUES
        (11, 'Вес'),
        (12, 'Объем');
 
INSERT INTO `product2options` (`product_id`, `option_id`, `value`) VALUES
        (1, 11, 200),
        (1, 12, 250),
        (2, 11, 35),
        (2, 12, 15),
        (3, 11, 310),
        (3, 12, 300),
        (2, 11, 45),
        (2, 12, 25);
Пример: выбрать товары, 
добавленные после 17/01/2009 в следующих вариантах:
- вес=310, объем=300
- вес=35, объем=15
- вес=45, объем=25
- вес=200, объем=250
Просто перечислить условия вариантов в подзапросе/джоине через OR/AND не сработает, 
необходимо осуществить объединение таблиц вариантов равное количеству этих самых вариантов (у нас - 2: объем и вес)
SELECT p.*, po1.name 'P1', p2o1.value, po2.name 'P2', p2o2.value     
 
FROM products p       
 
INNER JOIN product2options p2o1 ON p.id = p2o1.product_id
INNER JOIN product_options po1  ON po1.id = p2o1.option_id
 
INNER JOIN product2options p2o2 ON p.id = p2o2.product_id
INNER JOIN product_options po2  ON po2.id = p2o2.option_id
 
WHERE p.created_at > '2009-01-17 21:00' 
  AND ( -- тарелка#3 
  p2o1.option_id = 11 AND p2o1.value = 310 
  AND p2o2.option_id = 12 AND p2o2.value = 300
  OR  -- ложка#2
  p2o1.option_id = 11 AND p2o1.value = 35 
  AND p2o2.option_id = 12 AND p2o2.value = 15           
  OR  -- ложка#2
  p2o1.option_id = 11 AND p2o1.value = 45 
  AND p2o2.option_id = 12 AND p2o2.value = 25   
  OR  -- кружка#1 не попадает по дате
  p2o1.option_id = 12 AND p2o1.value = 250 
  AND p2o2.option_id = 11 AND p2o2.value = 200
  );
 Результ выборки:
id      title        created_at                P1        value    P2            value
2       Ложка        2009-01-18 20:00:00       Вес        35      Объем         15
3       Тарелка      2009-01-19 20:00:00       Вес        310     Объем         300
2       Ложка        2009-01-18 20:00:00       Вес        45      Объем         25
 
-- не попадает по дате
1       Кружка          2009-01-17 20:00:00     Объем   250     Вес             200

UPDATE и JOIN

Объединение можно использовать совместно с UPDATE. 
Например, имеем таблицу houses (id, title, area). Нужно выбрать title, если в нем встречается `число м2`, заменить поле area, если оно меньше. Т.к. в mysql отстутсутствует поддержка регулярных выражений, нужно немного поколдовать с locate и substr.
В подзапросе выбираем интересующие нас данные, и в финальной стадии осуществляем обновление данных подходящий по критерию (p5 > area).
UPDATE houses base
INNER JOIN (
-- Антарис аренда офиса 1594 м2, по ставке 12700 руб. м2/год -> 1594
SELECT
        id,
        @baseString := title title,
        @areaTitleEnd := LOCATE(' м2', @baseString) as p2,
        @tmpString := LTRIM(REVERSE(SUBSTR(@baseString, 1, @areaTitleEnd))) as p3,
        @areaTitleBegin := LEFT(@tmpString, -1 + LOCATE(' ', @tmpString)) as p4,
        @value := CAST(REVERSE(@areaTitleBegin) as UNSIGNED) as p5
 
        FROM ga_pageviews
        WHERE title like '%м2%'
) calc USING (`id`)
SET base.area = calc.p5
WHERE base.area < calc.p5

DELETE и JOIN

Рассмотрим пример с удалением дубликатов. Есть таблица tableWithDups (id, email). Нужно удалить строки с одинаковыми email:
DELETE tableWithDups
FROM tableWithDups
INNER JOIN (
        SELECT MAX(id) AS lastId, email
        FROM tableWithDups
        GROUP BY email
        HAVING COUNT(*) > 1
        ) dups ON dups.email = tableWithDups.email
WHERE tableWithDups.id < dups.lastId;
Последние два примера не совместимы с ANSI SQL, но работают в mySQL.
SQL