SQLinfo.ru - Все о MySQL Highload++ 2017

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 05.10.2017 16:32:04

jron
Завсегдатай
Зарегистрирован: 03.10.2017
Сообщений: 25

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

Вот мне нужен вот такой подзапрос:

необходимо вывести платежи, за тот день, когда был сделан наибольший платеж

SELECT * FROM payments WHERE paydate = (SELECT paydate FROM payments WHERE amount =
(SELECT MAX(amount) FROM payments));
 


Вот таблица из которой получаю подзапросы

mysql> select * from payments;
+-----+---------------------+----------+----------+
| num | paydate             | receiver | amount   |
+-----+---------------------+----------+----------+
|   1 | 2016-10-30 15:00:00 |        1 | 35000.50 |
|   2 | 2017-11-30 15:25:00 |        2 | 25000.50 |
|   3 | 2015-11-30 10:25:00 |        2 | 15000.50 |
|   4 | 2014-11-30 11:25:00 |        3 | 10000.50 |
|   5 | 2014-11-30 11:25:00 |        3 | 10000.50 |
|   6 | 2017-10-03 12:03:11 |        4 |  1000.50 |
|   7 | 2017-10-03 12:03:11 |        2 |   500.50 |
|   8 | 2017-10-03 12:03:11 |        3 | 17000.50 |
|   9 | 2017-10-03 12:03:11 |        1 |   100.50 |
|  10 | 2017-10-03 12:03:11 |        4 | 15000.50 |
|  11 | 2017-10-03 12:03:11 |        4 | 35000.50 |
|  12 | 2017-10-03 12:03:11 |        2 | 45000.50 |
|  13 | 2017-10-03 12:03:11 |        3 | 55000.50 |
|  14 | 2017-10-03 12:03:11 |        4 | 85000.50 |
|  15 | 2017-10-03 12:03:11 |        4 | 85000.50 |
|  16 | 2017-10-03 12:03:11 |        4 | 85000.50 |
+-----+---------------------+----------+----------+
16 rows in set (0.00 sec)


Вот я разложил запросы по мере их выполнения


mysql> select max(amount) from payments;
+-------------+
| max(amount) |
+-------------+
|    85000.50 |
+-------------+
1 row in set (0.02 sec)

mysql> SELECT paydate FROM payments WHERE amount = (SELECT MAX(amount) FROM payments);
+---------------------+
| paydate             |
+---------------------+
| 2017-10-03 12:03:11 |
| 2017-10-03 12:03:11 |
| 2017-10-03 12:03:11 |
+---------------------+
3 rows in set (0.00 sec)

mysql> SELECT * FROM payments WHERE paydate = (SELECT paydate FROM payments WHERE amount =
    -> (SELECT MAX(amount) FROM payments));
ERROR 1242 (21000): Subquery returns more than 1 row
mysql> SELECT * FROM payments WHERE paydate = (SELECT paydate FROM payments WHERE amount = (SELECT MAX(amount) FROM payments));
ERROR 1242 (21000): Subquery returns more than 1 row
mysql> select * from payments;


Если вложенный запрос содержит больше одной строки с максимальным значением , то появляется ошибка.
  Почему ?
Как это обойти ?

Неактивен

 

#2 05.10.2017 16:36:57

klow
Активист
Зарегистрирован: 06.12.2014
Сообщений: 236

Re: Вывод больше чем одну строку во вложенном подзапросе

SELECT * FROM payments WHERE date(paydate) = (SELECT date(paydate) FROM payments WHERE amount =
(SELECT MAX(amount) FROM payments) LIMIT 1);

Неактивен

 

#3 05.10.2017 16:38:04

klow
Активист
Зарегистрирован: 06.12.2014
Сообщений: 236

Re: Вывод больше чем одну строку во вложенном подзапросе

SELECT * FROM payments WHERE date(paydate) = (SELECT date(paydate) FROM payments ORDER BY amount desc LIMIT 1);

Отредактированно klow (05.10.2017 16:38:30)

Неактивен

 

#4 05.10.2017 16:39:57

jron
Завсегдатай
Зарегистрирован: 03.10.2017
Сообщений: 25

Re: Вывод больше чем одну строку во вложенном подзапросе

Простите поторопился.
Ответ на ошибку вроде нашел....

...если у вас два или больше платежа с такой величиной, второй подзапрос вернет несколько дат и сравнение с помощью знака равно, которое здесь использовано, не может работать, т.к. оператор равно не умеет сравнивать одно значение с несколькими.

mysql> SELECT * FROM payments WHERE paydate IN (SELECT paydate FROM payments WHERE amount =
    -> (SELECT MAX(amount) FROM payments));
+-----+---------------------+----------+----------+
| num | paydate             | receiver | amount   |
+-----+---------------------+----------+----------+
|   6 | 2017-10-03 12:03:11 |        4 |  1000.50 |
|   7 | 2017-10-03 12:03:11 |        2 |   500.50 |
|   8 | 2017-10-03 12:03:11 |        3 | 17000.50 |
|   9 | 2017-10-03 12:03:11 |        1 |   100.50 |
|  10 | 2017-10-03 12:03:11 |        4 | 15000.50 |
|  11 | 2017-10-03 12:03:11 |        4 | 35000.50 |
|  12 | 2017-10-03 12:03:11 |        2 | 45000.50 |
|  13 | 2017-10-03 12:03:11 |        3 | 55000.50 |
|  14 | 2017-10-03 12:03:11 |        4 | 85000.50 |
|  15 | 2017-10-03 12:03:11 |        4 | 85000.50 |
|  16 | 2017-10-03 12:03:11 |        4 | 85000.50 |
+-----+---------------------+----------+----------+
11 rows in set (0.00 sec)


Но как видите запрос корректно не отработал, подскажите почему

Неактивен

 

#5 05.10.2017 16:41:17

jron
Завсегдатай
Зарегистрирован: 03.10.2017
Сообщений: 25

Re: Вывод больше чем одну строку во вложенном подзапросе

Важно отработать использование оператора

IN

Неактивен

 

#6 05.10.2017 16:42:13

klow
Активист
Зарегистрирован: 06.12.2014
Сообщений: 236

Re: Вывод больше чем одну строку во вложенном подзапросе

А смысл? Вам нужно чтобы выводило все дни с максимальным платежом?

Отредактированно klow (05.10.2017 16:48:17)

Неактивен

 

#7 05.10.2017 16:42:49

jron
Завсегдатай
Зарегистрирован: 03.10.2017
Сообщений: 25

Re: Вывод больше чем одну строку во вложенном подзапросе

А если максимальные платежи будут различаться по времени за один и тот же день ???

Неактивен

 

#8 05.10.2017 16:43:19

jron
Завсегдатай
Зарегистрирован: 03.10.2017
Сообщений: 25

Re: Вывод больше чем одну строку во вложенном подзапросе

Таково задание урока...

Неактивен

 

#9 05.10.2017 16:47:31

jron
Завсегдатай
Зарегистрирован: 03.10.2017
Сообщений: 25

Re: Вывод больше чем одну строку во вложенном подзапросе

klow написал:

SELECT * FROM payments WHERE date(paydate) = (SELECT date(paydate) FROM payments ORDER BY amount desc LIMIT 1);

mysql> SELECT * FROM payments WHERE date(paydate) = (SELECT date(paydate) FROM payments ORDER BY amount desc LIMIT 1);
+-----+---------------------+----------+----------+
| num | paydate             | receiver | amount   |
+-----+---------------------+----------+----------+
|   6 | 2017-10-03 12:03:11 |        4 |  1000.50 |
|   7 | 2017-10-03 12:03:11 |        2 |   500.50 |
|   8 | 2017-10-03 12:03:11 |        3 | 17000.50 |
|   9 | 2017-10-03 12:03:11 |        1 |   100.50 |
|  10 | 2017-10-03 12:03:11 |        4 | 15000.50 |
|  11 | 2017-10-03 12:03:11 |        4 | 35000.50 |
|  12 | 2017-10-03 12:03:11 |        2 | 45000.50 |
|  13 | 2017-10-03 12:03:11 |        3 | 55000.50 |
|  14 | 2017-10-03 12:03:11 |        4 | 85000.50 |
|  15 | 2017-10-03 12:03:11 |        4 | 85000.50 |
|  16 | 2017-10-03 12:03:11 |        4 | 85000.50 |
+-----+---------------------+----------+----------+
11 rows in set (0.00 sec)


Задание не выполняется, нужно вывести день в который был совершен наибольший платеж
То есть вывести только строки с наибольшим платежем

Отредактированно jron (05.10.2017 16:49:11)

Неактивен

 

#10 05.10.2017 16:50:06

klow
Активист
Зарегистрирован: 06.12.2014
Сообщений: 236

Re: Вывод больше чем одну строку во вложенном подзапросе

Я не понял задачу. Можете привести четкую и полную формулировку задачи?

Неактивен

 

#11 05.10.2017 17:00:23

jron
Завсегдатай
Зарегистрирован: 03.10.2017
Сообщений: 25

Re: Вывод больше чем одну строку во вложенном подзапросе

оператор IN используется совместно с вложенными запросами.

пример.

Нам необходимо вывести платежи, за тот день, когда был сделан наибольший платеж в вашей базе., и показать строки только с наибольшим платежом

этот запрос ... не сработает если будет несколько одинаковых строк

SELECT * FROM payments WHERE paydate = (SELECT paydate FROM payments WHERE amount =
(SELECT MAX(amount) FROM payments));


вот так выведутся дни когда сделаны наибольшие платежи

SELECT * FROM payments WHERE paydate IN (SELECT paydate FROM payments WHERE amount =
(SELECT MAX(amount) FROM payments));
 

Неактивен

 

#12 05.10.2017 17:02:35

klow
Активист
Зарегистрирован: 06.12.2014
Сообщений: 236

Re: Вывод больше чем одну строку во вложенном подзапросе

А если есть несколько больших одинаковых платежей за разные дни?

Отредактированно klow (05.10.2017 17:03:54)

Неактивен

 

#13 05.10.2017 17:07:53

jron
Завсегдатай
Зарегистрирован: 03.10.2017
Сообщений: 25

Re: Вывод больше чем одну строку во вложенном подзапросе

у меня такой таблицы нет и в задаче так не сказано, но то же интересно решение

но очень интересует вопрос как показать только строки с наибольшими платежами

SELECT * FROM payments WHERE paydate IN (SELECT paydate FROM payments WHERE amount =
(SELECT MAX(amount) FROM payments));
 

Неактивен

 

#14 05.10.2017 17:17:14

klow
Активист
Зарегистрирован: 06.12.2014
Сообщений: 236

Re: Вывод больше чем одну строку во вложенном подзапросе

SELECT
  p.*
FROM payment p
  JOIN (SELECT date(paydate) paydate, amount FROM payments ORDER BY amount DESC LIMIT 1) d ON date(p.paydate) = d.paydate AND p.amount = d.amount;

Неактивен

 

#15 05.10.2017 17:31:49

jron
Завсегдатай
Зарегистрирован: 03.10.2017
Сообщений: 25

Re: Вывод больше чем одну строку во вложенном подзапросе

mysql> SELECT  p.*
    -> FROM payments p
    ->   JOIN (SELECT date(paydate) paydate, amount FROM payments ORDER BY amount DESC LIMIT 1) d
    ->   ON date(p.paydate) = d.paydate AND p.amount = d.amount;
+-----+---------------------+----------+----------+
| num | paydate             | receiver | amount   |
+-----+---------------------+----------+----------+
|  14 | 2017-10-03 12:03:11 |        4 | 85000.50 |
|  15 | 2017-10-03 12:03:11 |        4 | 85000.50 |
|  16 | 2017-10-03 12:03:11 |        4 | 85000.50 |
+-----+---------------------+----------+----------+
3 rows in set (0.00 sec)
 

Неактивен

 

#16 05.10.2017 17:45:24

jron
Завсегдатай
Зарегистрирован: 03.10.2017
Сообщений: 25

Re: Вывод больше чем одну строку во вложенном подзапросе

поясните пожалуйста значение ON - в данном контексте
и date(p.paydate)....
Вы использовали в запросе описания типа данных ?

Отредактированно jron (05.10.2017 17:46:16)

Неактивен

 

#17 05.10.2017 20:01:11

klow
Активист
Зарегистрирован: 06.12.2014
Сообщений: 236

Re: Вывод больше чем одну строку во вложенном подзапросе

Функция date() преобразует значение DateTime в Date.

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson