Гость
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Выборка данных, совпадающих в разных строках по нескольким полям одновременно / 25 сообщений из 25, страница 1 из 1
01.03.2019, 14:43
    #39781040
DMKov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка данных, совпадающих в разных строках по нескольким полям одновременно
Есть таблица, содержащая, в том числе, поля
field1 | field2 | fiel3 | field4
51 | 1 | 0.5 | 9
48 | 0.7 | 0.5 | 2
51 | 1 | 0.5 | 9
11 | 1 | 1 | 8
51 | 1 | 1.5 | 1
51 | 1 | 0.5 | 9

Мне нужно выбрать те строки, где совпадают все значения во всех четырёх полях, в данном случае это три строки:
51 | 1 | 0.5 | 9

Перепробовал кучу способов. Все они выводят в данном примере 4 строки - все, где в первом поле 51.

Есть идеи?
...
Рейтинг: 0 / 0
01.03.2019, 14:45
    #39781042
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка данных, совпадающих в разных строках по нескольким полям одновременно
Код: sql
1.
2.
GROUP BY field1, field2, fiel3, field4
HAVING COUNT(*) > 1
...
Рейтинг: 0 / 0
01.03.2019, 14:46
    #39781044
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка данных, совпадающих в разных строках по нескольким полям одновременно
PS. Если fields3 - это float/double, возможны проблемы. Сменить на DECIMAL или текстовый.
...
Рейтинг: 0 / 0
01.03.2019, 14:56
    #39781052
DMKov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка данных, совпадающих в разных строках по нескольким полям одновременно
Akina
Код: sql
1.
2.
GROUP BY field1, field2, fiel3, field4
HAVING COUNT(*) > 1



Я пробовал. Выводит
51 | 0.70 | 1.00 | 1.00
51 | 0.70 | 1.00 | 0.90
51 | 0.70 | 1.00 | 0.90
51 | 0.70 | 1.00 | 1.00
51 | 0.70 | 1.00 | 1.00
51 | 0.70 | 1.00 | 1.00
51 | 0.70 | 1.00 | 0.75
51 | 0.70 | 0.50 | 1.00
...
Рейтинг: 0 / 0
01.03.2019, 14:57
    #39781054
DMKov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка данных, совпадающих в разных строках по нескольким полям одновременно
AkinaPS. Если fields3 - это float/double, возможны проблемы. Сменить на DECIMAL или текстовый.
Первое поле int, остальные decimal
...
Рейтинг: 0 / 0
03.03.2019, 14:03
    #39781498
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка данных, совпадающих в разных строках по нескольким полям одновременно
DMKovЯ пробовал. ВыводитПоказывайте весь запрос. Потому как показанный вывод противоречит предложенному фрагменту.
...
Рейтинг: 0 / 0
04.03.2019, 11:21
    #39781785
DMKov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка данных, совпадающих в разных строках по нескольким полям одновременно
AkinaПоказывайте весь запрос. Потому как показанный вывод противоречит предложенному фрагменту.

Вот, только что:

SELECT `field1`,`field2`,`field3`,`field4`
FROM `test`
WHERE `region` = 'Регион'
GROUP BY `field1`,`field2`,`field3`,`field4`
HAVING COUNT(*) > 1
ORDER BY `field1`,`field2`,`field3`,`field4`

field1 | field2 | field3 | field4
38 | 0.70 | 0.50 | 1.00
43 | 0.70 | 0.50 | 1.00
45 | 0.70 | 0.50 | 1.00
45 | 0.70 | 1.00 | 0.90
45 | 0.70 | 1.00 | 1.00
46 | 0.70 | 0.50 | 0.90
48 | 0.70 | 1.00 | 0.90
49 | 0.70 | 1.00 | 0.90
51 | 0.70 | 1.00 | 0.75
51 | 0.70 | 1.00 | 0.90
51 | 0.70 | 1.00 | 1.00

Ну и так далее.
Такая выборка даёт по 1 строке из нескольких совпадений.
Т.е., например, я вижу, что в таблице есть три строки с показателями 51 | 0.70 | 1.00 | 0.90.
А выводится одна. Что мне с ней делать?
Мне нужно все три изменить. Вернее, две (чётное количество).
Мне в одинаковых строках нужно число в первой колонке в каждой паре нечётное уменьшить на случайное число от 1 до 3, чётное - соответственно, увеличить на это же число.
...
Рейтинг: 0 / 0
04.03.2019, 12:23
    #39781831
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка данных, совпадающих в разных строках по нескольким полям одновременно
DMKovМне нужно все три изменить. Вернее, две (чётное количество).Так. Приехали... что в начале было?
DMKovМне нужно выбрать те строки
Давайте всё же решать ОДНУ задачу.

Давайте так. Сделайте модельный fiddle (например, на dbfiddle.uk или db-fiddle.com) на десяток записей (ну или просто тут выложите create table + insert into), покажите требуемый результат на именно этих данных, и с объяснениями, почему именно так. И будем решать именно эту задачу, не меняя и не дополняя её на полпути.
...
Рейтинг: 0 / 0
04.03.2019, 13:40
    #39781903
DMKov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка данных, совпадающих в разных строках по нескольким полям одновременно
AkinaДавайте всё же решать ОДНУ задачу.

Спасибо. Давайте. Вот сама задача:

Требуется выбрать из базы данных строки, в которых четыре поля полностью совпадают, например, 51 | 0.70 | 1.00 | 1.00.
Заранее неизвестно, в каких строках есть совпадения, каких именно числовых данных и сколько таких строк.

Затем требуется изменить первое поле в парах на случайное число от 1 до 3. Последнее нечётное значение не меняем.
Т.е., если две строчки - меняем два значения и получаем, например, 52 | 0.70 | 1.00 | 1.00 и 50 | 0.70 | 1.00 | 1.00.
Если три строки - то же самое.
Если четыре или пять, то меняем четыре значения и получаем, к примеру:
52 | 0.70 | 1.00 | 1.00
50 | 0.70 | 1.00 | 1.00
53 | 0.70 | 1.00 | 1.00
49 | 0.70 | 1.00 | 1.00
51 | 0.70 | 1.00 | 1.00

Если теперь вычислить поле1 * (поле2 + поле3 + поле4)/3, то средний результат в двух парных строках будет одинаковый, такой же, какой был в исходном наборе данных (51 * (0,7+1+1)/3 = 45.90). (Эти вычисления проводить не нужно)

И так проходим всю таблицу.
...
Рейтинг: 0 / 0
04.03.2019, 16:36
    #39782107
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка данных, совпадающих в разных строках по нескольким полям одновременно
Теперь укажите точную версию MySQL.
Ибо для 8+ можно составить достаточно эффективный запрос с использованием CTE. А вот для 5-й версии разумнее написать хранимую процедуру - решение в виде запроса там получится весьма монстрообразным.

Идея в любом случае будет такая. Каждую запись дополняем двумя полями - общее количество дубликатов в группе, и номер записи в группе. После чего нечётные инкрементим, чётные декрементим, последнюю, если она нечётная, не трогаем. А вот реализация будет различаться кардинально.

Ну и следует понимать, что понятие "пара" в данном случае - не существует, ибо таблица есть куча, и порядок записей в ней не определён. Просто сколько-то плюсим, сколько-то минусим...
...
Рейтинг: 0 / 0
04.03.2019, 17:59
    #39782174
DMKov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка данных, совпадающих в разных строках по нескольким полям одновременно
AkinaТеперь укажите точную версию MySQL.

Сервер: MySQL (Localhost via UNIX socket)
Тип сервера: Percona Server
Версия сервера: 5.7.23-24 - Percona Server (GPL), Release 24, Revision 57a9574
Версия протокола: 10
...
Рейтинг: 0 / 0
05.03.2019, 07:45
    #39782317
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка данных, совпадающих в разных строках по нескольким полям одновременно
Ну если 5.7, то нужно что-то вроде (драфт):

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
create temporary table temp (field1, field2, field3, field4, cnt) /* engine=memory */ ;
insert into temp 
    select field1, field2, field3, field4, floor(count(*)/2)
    from datatable
    group by field1, field2, field3, field4;
create cursor cur as select field1, field2, field3, field4, cnt from temp;
open cur;
set @ done:=0;
create continue handler for not found set @done:=1;
fetch cur into @field1, @field2, @field3, @field4, @cnt;
repeat:
-- следующую строку переделать, собрать корректный запрос в переменной с помощью CONCAT()
    @sql:='update datatable set field1=field1+1 where (field1, field2, field3, field4) in (@field1, @field2, @field3, @field4) limit @cnt'; 
    prepare stmt from @sql;
    exec stmt;
    deallocate stmt;
-- следующую строку переделать, собрать корректный запрос в переменной с помощью CONCAT()
    @sql:='update datatable set field1=field1-1 where (field1, field2, field3, field4) in (@field1, @field2, @field3, @field4) limit @cnt'; 
    prepare stmt from @sql;
    exec stmt;
    deallocate stmt;
    fetch cur into @field1, @field2, @field3, @field4, @cnt;
    until @done end repeat;
...
Рейтинг: 0 / 0
05.03.2019, 07:48
    #39782318
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка данных, совпадающих в разных строках по нескольким полям одновременно
Если же структура исходной таблицы допускает изменение (в неё допустимо добавить поле), то задача значительно упростится. Теоретически так и должно быть, если нигде в коде не используется позиционная зависимость полей.
...
Рейтинг: 0 / 0
05.03.2019, 13:38
    #39782481
DMKov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка данных, совпадающих в разных строках по нескольким полям одновременно
AkinaНу если 5.7, то нужно что-то вроде (драфт):

Ого! Вот такого никогда не делал и не додумался бы! Здорово!
...
Рейтинг: 0 / 0
05.03.2019, 13:39
    #39782482
DMKov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка данных, совпадающих в разных строках по нескольким полям одновременно
AkinaЕсли же структура исходной таблицы допускает изменение (в неё допустимо добавить поле), то задача значительно упростится. Теоретически так и должно быть, если нигде в коде не используется позиционная зависимость полей.

да, я легко могу добавить одно или несколько полей.
...
Рейтинг: 0 / 0
05.03.2019, 13:49
    #39782488
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка данных, совпадающих в разных строках по нескольким полям одновременно
DMKovя легко могу добавить одно или несколько полей.Ну тогда задача упрощается. добавьте поле, и первым шагом пронумеруйте записи в каждой группе (используйте переменные, см. FAQ раздела). А дальше получаете в подзапросе макс. номер для каждой группы, и на основе FLOOR(MAX(count)/2) либо плюсуете, либо минусуете, либо не трогаете. Всё уложится в два запроса.
...
Рейтинг: 0 / 0
05.03.2019, 15:20
    #39782544
DMKov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка данных, совпадающих в разных строках по нескольким полям одновременно
Akinaдобавьте поле, и первым шагом пронумеруйте записи в каждой группе (используйте переменные, см. FAQ раздела). А дальше получаете в подзапросе макс. номер для каждой группы, и на основе FLOOR(MAX(count)/2) либо плюсуете, либо минусуете, либо не трогаете. Всё уложится в два запроса.

Это для меня непонятно.

Я попробовал код выше - выдаёт ошибку:

CREATE cursor cur AS SELECT field1, field2, field3, field4, cnt
FROM temp;

Ответ MySQL: Документация

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'cursor cur as select field1, field2, field3, field4, cnt from temp' at line 1
...
Рейтинг: 0 / 0
05.03.2019, 15:36
    #39782557
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка данных, совпадающих в разных строках по нескольким полям одновременно
Ну вообще-то написанный мной код - это тело хранимой процедуры. В MySQL нет анонимного кода. Так что Вы явно забыли создать это "обрамление".
...
Рейтинг: 0 / 0
05.03.2019, 15:36
    #39782558
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка данных, совпадающих в разных строках по нескольким полям одновременно
Ну и - коли сие драфт, то его непременно надо подрихтовать под правильный синтаксис.
...
Рейтинг: 0 / 0
05.03.2019, 18:09
    #39782664
DMKov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка данных, совпадающих в разных строках по нескольким полям одновременно
Akina, спасибо.
К сожалению, знаний не хватает, чтобы воспользоваться вашей подсказкой.
Пойду длинным путём, как умею - переберу все данные. Правда, там больше 8000 строк.
...
Рейтинг: 0 / 0
06.03.2019, 13:03
    #39782929
DMKov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка данных, совпадающих в разных строках по нескольким полям одновременно
Akinaдобавьте поле, и первым шагом пронумеруйте записи в каждой группе (используйте переменные, см. FAQ раздела). А дальше получаете в подзапросе макс. номер для каждой группы, и на основе FLOOR(MAX(count)/2) либо плюсуете, либо минусуете, либо не трогаете. Всё уложится в два запроса.

А можете подсказать эти два запроса? А то как рыба об лёд...
...
Рейтинг: 0 / 0
06.03.2019, 13:32
    #39782956
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка данных, совпадающих в разных строках по нескольким полям одновременно
DMKovА то как рыба об лёд...Значит, первым делом читаем FAQ: Нумерация строк и другие вопросы про использование переменных , пост "Выборка нескольких последних записей в неких группах". Отбрасываем обёртку, которая отбирает заданное количество, оставляем нумерующую начинку.

Это практически первый запрос. Сделайте сначала его. Уж удалить обёртку да подставить свои имена таблицы и полей - справитесь?
...
Рейтинг: 0 / 0
06.03.2019, 20:22
    #39783222
DMKov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка данных, совпадающих в разных строках по нескольким полям одновременно
Akina, а можно как-то получить просто выборку нужных строк, а все операции я в php сделаю?
Мне нужно-то - получить все строки (id строк), где совпадают поля 1-4. Дальше я в php делаю нужные операции и update table.
...
Рейтинг: 0 / 0
06.03.2019, 20:33
    #39783224
DMKov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка данных, совпадающих в разных строках по нескольким полям одновременно
AkinaОтбрасываем обёртку, которая отбирает заданное количество, оставляем нумерующую начинку.
Это практически первый запрос. Сделайте сначала его. Уж удалить обёртку да подставить свои имена таблицы и полей - справитесь?
Мне просто логика всё равно непонятна. Какая нумерация, для чего, как её потом использовать и т.д.

С БД до сих пор я работал просто, обычными запросами, без конкатов, джойнов и тем более, без переменных. Можно, конечно, погрузиться в тему. Но ради решения одной задачи?

Поэтому я и хотел изначально получить все строки (id строк), где совпадают поля 1-4. Дальше я в php делаю нужные операции и update table.

Да, в любом случае, спасибо за помощь - это очень интересно, я вообще понятия не имел о переменных в MySQL.
...
Рейтинг: 0 / 0
08.03.2019, 08:33
    #39783818
DMKov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка данных, совпадающих в разных строках по нескольким полям одновременно
Akina, я сделал по-своему :-)
Не скажу, что решение изящное, но работает, как часы.

Напомню задачу:
Требуется выбрать из базы данных строки, в которых четыре поля полностью совпадают, например, 51 | 0.70 | 1.00 | 1.00.
Заранее неизвестно, в каких строках есть совпадения, каких именно числовых данных и сколько таких строк.

Затем требуется изменить первое поле в парах на случайное число от 1 до 3. Последнее нечётное значение не меняем.
Т.е., если две строчки - меняем два значения и получаем, например, 52 | 0.70 | 1.00 | 1.00 и 50 | 0.70 | 1.00 | 1.00.
Если три строки - то же самое.
Если четыре или пять, то меняем четыре значения и получаем, к примеру:
52 | 0.70 | 1.00 | 1.00
50 | 0.70 | 1.00 | 1.00
53 | 0.70 | 1.00 | 1.00
49 | 0.70 | 1.00 | 1.00
51 | 0.70 | 1.00 | 1.00

Если теперь вычислить поле1 * (поле2 + поле3 + поле4)/3, то средний результат в двух парных строках будет одинаковый, такой же, какой был в исходном наборе данных (51 * (0,7+1+1)/3 = 45.90). (Эти вычисления проводить не нужно)

И так проходим всю таблицу.

Ну и вот что получилось:

Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
<?	
// берем все оценки по очереди 
$query2 = "SELECT `id`, `field1`, `field2`, `field3`, `field4` FROM `datatable` ORDER BY `field1`, `field2`, `field3`, `field4` FROM `datatable`";
$result2 = mysqli_query ($link, $query2);
$id = "0";
while($row2=mysqli_fetch_array($result2)) {
	$id_1 = $row2["id"];
	$field1 = $row2["field1"];
	$field2 = $row2["field2"];
	$field3 = $row2["field3"];
	$field4 = $row2["field4"];

	$query3 = "SELECT `id`, `field1`, `field2`, `field3`, `field4` FROM `datatable` WHERE `field1` = '$field1'  AND `field2` = '$field2'  AND `field3` = '$field3'  AND `field4` = '$field4' AND `id` NOT IN (".$id.") ORDER BY `field1`, `field2`, `field3`, `field4`";

	$result3 = mysqli_query ($link, $query3);
	$num = mysqli_num_rows($result3);
	if($num > 1){ // тут можно поставить нужное количество совпадений
		if(($num % 2) == 0)// чётное 
			$i = $num;
		else
		   $i = $num - 1; // убираем нечётное совпадение
		while($row3=mysqli_fetch_array($result3) AND $i > 0){
			$id_3 = $row3["id"];
			$change_even = rand(1, 5); // случайное число от 1 до 5, на которое будем увеличивать и уменьшать
			if(($i % 2) == 0){ // для чётных
				$query4 = "UPDATE `datatable` SET field1 = field1 + '$change_even' WHERE id = '$id_3'";
				mysqli_query ($link, $query4);
				$change = $change_even; // чтобы отнять такое же число
			}
			else{ // для нечётных
				$query5 = "UPDATE `datatable` SET field1 = field1 - '$change' WHERE id = '$id_3'";
				mysqli_query ($link, $query5);
			}
			$id = $id.",".$row3["id"]; // исключаем из поиска обработанные строки
			$i--;
			}
	}
}
?>
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Выборка данных, совпадающих в разных строках по нескольким полям одновременно / 25 сообщений из 25, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]