Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Web программирование > SQL, базы данных
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 25.06.2018, 17:49   #1
Parallelogram
Недотепа
Форумчанин
 
Регистрация: 18.01.2011
Сообщений: 174
По умолчанию Подсчет количества строк с совпадением

Решение задачи я реализовал на php, но хотелось бы на mysql.

Делаю реферальную систему до 3 уровня. Юзер хранит id родителя. Нужно подсчитать количество рефералов на каждом уровне до третьего.

id | ref
1 | 0
2 | 0
3 | 2
4 | 1
5 | 2
6 | 4
7 | 3
8 | 7
9 | 3

Если подсчитать для id=2, то должно получиться lvl1=2, lvl2=2, lvl3=1.

Вот тестовый вариант на php:
Код:
<?php
$lvl_1 = $lvl_2 = $lvl_3 = '0';

function _lvl($lvl_1=0, $lvl_2=0, $lvl_3=0) {
	echo 'lvl_1 = '.$lvl_1.'<br>';
	echo 'lvl_2 = '.$lvl_2.'<br>';
	echo 'lvl_3 = '.$lvl_3.'<br>';
}

$select1 = "SELECT `id` FROM `table` WHERE `r`=2";
$query_select1 = mysqli_query($bd, $select1);

if ($query_select1) {
	$lvl_1 = mysqli_num_rows($query_select1);
	while ($row1 = mysqli_fetch_assoc($query_select1)) { $arr1[] = $row1['id']; }
} else {
	exit;
}
if ($lvl_1 == 0) {
	_lvl($lvl_1);
	exit;
}



$select2 = "SELECT `id` FROM `table` WHERE `r` IN (".implode(",", $arr1).")";
$query_select2 = mysqli_query($bd, $select2);

if ($query_select2) {
	$lvl_2 = mysqli_num_rows($query_select2);
	while ($row2 = mysqli_fetch_assoc($query_select2)) { $arr2[] = $row2['id']; }
} else {
	exit;
}
$sum = (int)$lvl_1+(int)$lvl_2;
if ($lvl_2 == 0) {
	_lvl($lvl_1, $lvl_2);
	exit;
}




$select3 = "SELECT `id` FROM `table` WHERE `r` IN (".implode(",", $arr2).")";
$query_select3 = mysqli_query($bd, $select3);

if ($query_select3) {
	$lvl_3 = mysqli_num_rows($query_select3);
	while ($row3 = mysqli_fetch_assoc($query_select3)) { $arr3[] = $row3['id']; }
} else {
	exit;
}
$sum = (int)$lvl_1+(int)$lvl_2+(int)$lvl_3;
echo 'Sum = '.$sum.'<br>';
_lvl($lvl_1, $lvl_2, $lvl_3);?>
Как то же самой реализовать на на mysql?
Parallelogram вне форума Ответить с цитированием
Старый 26.06.2018, 10:43   #2
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 19,042
По умолчанию

Отдельными запросами для каждого уровня. Если для конкретного id where добавь
Код:
SELECT T1.id,COUNT(T2.ref) AS Count1
  FROM MyTable T1,MyTable T2 
  WHERE T2.ref=T1.id
  GROUP BY T1.id

SELECT T1.id,COUNT(T3.ref) AS Count2
  FROM MyTable T1,MyTable T2,MyTable T3 
  WHERE T2.ref=T1.id AND T3.ref=T2.id
  GROUP BY T1.id

SELECT T1.id,COUNT(T4.ref) AS Count3
  FROM MyTable T1,MyTable T2,MyTable T3,MyTable T4
  WHERE T2.ref=T1.id AND T3.ref=T2.id AND T4.ref=T3.id
  GROUP BY T1.id
Одним запросом для мускула влом думать. Для сиквела сделал бы так
Код:
SELECT T1.id,
    COUNT(DISTINCT T2.id) AS Count1,
    COUNT(DISTINCT T3.id) AS Count2,
    COUNT(DISTINCT T4.id) AS Count3
  FROM MyTable T1
    LEFT JOIN MyTable T2 ON T2.ref=T1.id
    LEFT JOIN MyTable T3 ON T3.ref=T2.id
    LEFT JOIN MyTable T4 ON T4.ref=T3.id
  GROUP BY T1.id
можно на сиквеле и рекурсивным запросом с with и на большую глубину
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию

Последний раз редактировалось Аватар; 26.06.2018 в 10:49.
Аватар вне форума Ответить с цитированием
Старый 27.06.2018, 02:57   #3
Parallelogram
Недотепа
Форумчанин
 
Регистрация: 18.01.2011
Сообщений: 174
По умолчанию

Спасибо. Все работает и для одного id и для всех id.
Код:
SELECT 
  T1.id,
  COUNT(T2.ref) AS сount1,
  (SELECT COUNT(T3.ref)
    FROM MyTable T1, MyTable T2,MyTable T3 
    WHERE T2.ref=T1.id AND T3.ref=T2.id AND T1.id=2
  ) AS сount2,
  (SELECT COUNT(T4.ref)
    FROM MyTable T1, MyTable T2, MyTable T3, MyTable T4
    WHERE T2.ref=T1.id AND T3.ref=T2.id AND T4.ref=T3.id AND T1.id=2
  ) AS сount3
FROM MyTable T1, MyTable T2 
WHERE T2.ref=T1.id AND T1.id=2
Код:
SELECT T1.id,
  COUNT(DISTINCT T2.id) AS Count1,
  COUNT(DISTINCT T3.id) AS Count2,
  COUNT(DISTINCT T4.id) AS Count3
FROM MyTable T1
  LEFT JOIN MyTable T2 ON T2.ref=T1.id
  LEFT JOIN MyTable T3 ON T3.ref=T2.id
  LEFT JOIN MyTable T4 ON T4.ref=T3.id
WHERE T1.id=2
Parallelogram вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Подсчет количества строк Чекмарь Microsoft Office Excel 14 10.11.2016 12:08
подсчет количества строк в memo igabenu Помощь студентам 10 06.11.2010 16:49
Подсчет количества строк в БД (Delphi 7) NuR1k БД в Delphi 8 30.08.2010 03:57
Подсчет количества заполненных строк. fuzzylogic Microsoft Office Excel 8 11.03.2010 18:37