Форум программистов
 
Контакты: о проблемах с регистрацией, почтой и по другим вопросам пишите сюда - alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail.

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

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

Ответ
 
Опции темы
Старый 25.06.2018, 18:49   #1
Parallelogram
Форумчанин
 
Регистрация: 18.01.2011
Адрес: Живу по адресу: Parallelogram@list.ru
Сообщений: 144
Репутация: 35
По умолчанию Подсчет количества строк с совпадением

Решение задачи я реализовал на 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, 11:43   #2
Аватар
Модератор
Заслуженный модератор
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Адрес: Северодонецк.ua
Сообщений: 17,900
Репутация: 6285
По умолчанию

Отдельными запросами для каждого уровня. Если для конкретного 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 в 11:49.
Аватар вне форума   Ответить с цитированием
Старый 27.06.2018, 03:57   #3
Parallelogram
Форумчанин
 
Регистрация: 18.01.2011
Адрес: Живу по адресу: Parallelogram@list.ru
Сообщений: 144
Репутация: 35
По умолчанию

Спасибо. Все работает и для одного 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 вне форума   Ответить с цитированием
Ответ

Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

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


05:20.


Powered by vBulletin® Version 3.8.8 Beta 2
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.

RusProfile.ru


Справочник российских юридических лиц и организаций.
Проекты отопления, пеллетные котлы, бойлеры, радиаторы
интернет магазин respective.ru