|   |   | 
| 
 | Помогите разобраться с SQL | ☑ | ||
|---|---|---|---|---|
| 0
    
        1сПупс 27.09.22✎ 15:19 | 
        Есть таблица Transactions (колонки id, id_products, id_store, date)
 есть таблица Products (id, name) есть таблица store(id, name) Как мне в запросе вывести не только айдишники продуктов и магазинов, но их имена? | |||
| 13
    
        bolder 27.09.22✎ 18:39 | 
        (7) Можно но не нужно.Затраты на выполнение (11) в 4 раза больше (5), два Hash Match убивают производительность.     | |||
| 14
    
        Said_We 27.09.22✎ 18:56 | 
        (0) Можно и так.
 Select (SELECT name from products as t1 where t.id_products = t1.id limit 1) as name_product ,(SELECT name from store as t2 where t.id_store = t2.id limit 1) as name_store from Transactions as t | |||
| 15
    
        Said_We 27.09.22✎ 18:58 | 
        Точнее так
 Select (SELECT t1.name from products as t1 where t.id_products = t1.id limit 1) as name_product ,(SELECT t2.name from store as t2 where t.id_store = t2.id limit 1) as name_store from Transactions as t | |||
| 16
    
        Said_We 27.09.22✎ 19:16 | 
        Не нужны тут соединения. Это стандартная задача.     | |||
| 17
    
        Злопчинский 27.09.22✎ 23:25 | 
        (16) а почему соединения не нужны?
 на большом объеме данных - какой вариант будет лучше - с соединениями или без? | |||
| 18
    
        mistеr 27.09.22✎ 23:30 | 
        (13) Ты с настоящим SQL только по книжкам знаком? Планы будут одинаковые.     | |||
| 19
    
        mistеr 27.09.22✎ 23:32 | 
        (15) В реальной жизни за такое бьют по рукам.     | |||
| 20
    
        DrZombi гуру 28.09.22✎ 06:51 | 
        (0) Почитайте про соединения :)
 https://www.sqlshack.com/learn-sql-inner-join-vs-left-join/ Статья англо, но Хром вам поможет :) | |||
| 21
    
        DrZombi гуру 28.09.22✎ 06:52 | 
        (11) Вы ресурсы не экономите... Вижу черту 1С-ника :)     | |||
| 22
    
        NorthWind 28.09.22✎ 06:55 | 
        (11) компактнее и, на мой взгляд, удобнее. У Оракла еще есть оператор (+) для обозначения опциональной таблицы в соединении, если хочешь писать так, т.е. можно ... WHERE LeftTable.ID(+)=RightTable.LeftID. Как по мне - удобно.     | |||
| 23
    
        DrZombi гуру 28.09.22✎ 06:55 | 
        (7) Если вам скорость не важна, и вы любите простым запросиком вешать SQL, то можно и без соединений :)     | |||
| 24
    
        NorthWind 28.09.22✎ 08:23 | 
        (21) это вполне нормальный запрос. Просто синтаксис SQL немного другой. См. (18).     | |||
| 25
    
        Said_We 28.09.22✎ 11:04 | 
        (19) Прямые запросы в 1С77 такие конструкции использует. По рукам никого не били и не переписали.     | |||
| 26
    
        Said_We 28.09.22✎ 11:13 | 
        (25) Прямые запросы имеется ввиду 1С++ на 77 и класс "Прямой запрос".     | |||
| 27
    
        Said_We 28.09.22✎ 11:18 | 
        В случае с внутренним и левым соединением, присутствием id_products в таблице Transactions и отсутствием ID в таблице Products количество записей будет разное.
 С id_store аналогично. И это тоже жизнь - битые ссылки. | |||
| 28
    
        Said_We 28.09.22✎ 11:28 | 
        (17) Вариант в (15) отработает быстро. Там для каждой записи таблицы Transactions отбирается первая попавшиеся запись из таблиц Products и store по соответствующим полям с ID.     | |||
| 29
    
        mistеr 28.09.22✎ 11:28 | 
        (25) Я имею в виду в не-1С разработке.     | |||
| 30
    
        Said_We 28.09.22✎ 11:33 | 
        (29) В стандартной разработке на 1С такие конструкции не поддерживаются.
 В не стандартной 1С++ на 1С 77 использовали именно эту конструкцию (ещё лет 15-17 назад). Она корректнее отрабатывает в случае с не корректными данными и по времени достаточно быстро. | |||
| 31
    
        Said_We 28.09.22✎ 21:23 | 
        (0) Так запрос в (15) подойдет?     | |||
| 32
    
        bolder 28.09.22✎ 21:28 | 
        (18) Я не теоретик, как вы.План запросов показывает 4-х кратное снижение производительстности без соединений, как я и писал в (13):
 https://ibb.co/WcPKNrv | |||
| 33
    
        Said_We 28.09.22✎ 22:07 | 
        (32) А без джойнов?     | |||
| 34
    
        DrZombi гуру 29.09.22✎ 06:21 | 
        (24)  Посмотрите, тут люди уже доказывают обратное в (32)  :)     | |||
| 35
    
        katamoto 29.09.22✎ 06:38 | 
        (32) Не показательно, на самом деле. Это планы только на ваших тестовых данных, в реальности они могу быть совершенно другие, в зависимости от количества строк в таблицу и наличия индексов     | |||
| 36
    
        DrZombi гуру 29.09.22✎ 06:42 | 
        (35) В общем, для стабильности, ИМХО - если чего, лучше связи прописывать :)
 И INNER работает тормознутее, чем тот же LEFT (для справки, если чего) :) | |||
| 37
    
        katamoto 29.09.22✎ 07:01 | 
        (36) Inner join и left join это логические операторы, так что бессмысленно говорить что один из них быстрее другого. Нужно смотреть какие физические методы доступа оптимизатор решит использовать в конкретном случае. А это уже сильно зависит от множества других факторов, по одному тексту запроса сказать нельзя.     | |||
| 38
    
        DrZombi гуру 29.09.22✎ 07:32 | 
        (37) Ну да, нуда... Вы как начнете использовать Терабайтные базы в SQL запросах, то не забудьте поиграться Join-ами, вас позабавит разница в Left и Inner :)     | |||
| 39
    
        mistеr 29.09.22✎ 07:44 | 
        (32) Если хочешь быть практиком, то:
 1) наполни таблицы более-менее реальным количеством данных; в частности, transactions >> products >> store 2) добавь необходимые индексы 3) собери статистику 4) смотри на реальную статистику выполнения, а не только план. | |||
| 40
    
        katamoto 29.09.22✎ 07:45 | 
        (38) Объем базы абсолютно ничего не говорит о квалификации того, кто с ней работает, в общем-то     | |||
| 41
    
        mistеr 29.09.22✎ 07:54 | 
        (36) Интересно, в каких случаях и почему?     | |||
| 42
    
        Said_We 29.09.22✎ 10:11 | 
        (32) А без джоинов как в (15) за сколько отработает?     | |||
| 43
    
        Said_We 29.09.22✎ 11:46 | 
        (32) Пробовать значит не будите.....     | |||
| 44
    
        Said_We 29.09.22✎ 15:00 | 
        (32) хозяин барин....     | |||
| 45
    
        Курцвейл 29.09.22✎ 15:40 | 
        (38) Inner ВСЕГДА быстрее LEFT за редким исключением. Исключение - кривые руки проектировщика решения.     | |||
| 46
    
        bolder 29.09.22✎ 16:32 | 
        (43) Я попытался скопировать ваш код из (15) но запрос не выполняется из-за ошибки идентификатора t.id_products не может получить.
 MSSQL 2014.На другом сервере пока не могу попробовать, просто нет времени. | |||
| 47
    
        Sserj 29.09.22✎ 16:33 | 
        (42) Тут вобщем то ни разу не сказали что за движок базы. А судя по (2) это и вовсе не ms-sql а что-то типа sqlite или mysql.
 Ну так вот в MS-SQL с вероятностью процентов 95 эти запросы развернутся в left join. Свежие sql-серверы очень умные штуки. | |||
| 48
    
        bolder 29.09.22✎ 16:34 | 
        (47) Результаты в (32) получены на MSSQL 2014     | |||
| 49
    
        bolder 29.09.22✎ 16:36 | 
        (39) Проведу такие эксперименты, но до выходных просто физически нет времени.     | |||
| 50
    
        Мультук гуру 29.09.22✎ 16:39 | 
        (49) 
 Если уж сравнивать планы,то LEFT JOIN INNER JOIN Неявный Inner join А сравнивать Left join И неявный inner join -- такое себе счастье | |||
| 51
    
        Said_We 29.09.22✎ 16:40 | 
        (46) В описании в (0) поле называется "id_products" судя по (32) называется "id_prod", а может поле называется "id_product".     | |||
| 52
    
        bolder 29.09.22✎ 16:44 | 
        (51) Не не я десять раз идентификаторы сверил.Проблема именно вовнутреннем условии на внешнее поле.Если у кого-то получилось, был бы рад посмотреть.     | |||
| 53
    
        Said_We 29.09.22✎ 16:51 | 
        (52) Рабочий способ. Поддерживается и Ораклом и MS SQL и MySQL и SQLite и...
 https://sql-academy.org/ru/trainer/tasks/1 SELECT t1.id ,(SELECT t.name FROM passenger as t WHERE t1.passenger = t.id ) as name FROM Pass_in_trip as t1 | |||
| 54
    
        Said_We 29.09.22✎ 16:55 | 
        К (53) Limit 1 не указал. На старых версиях MYSQL не отработает. Для MS SQL соответственно TOP 1 и может потребовать ORDER BY t.id.
 SELECT t1.id ,(SELECT t.name FROM passenger as t WHERE t1.passenger = t.id limit 1) as name FROM Pass_in_trip as t1 | |||
| 55
    
        Said_We 29.09.22✎ 16:57 | 
        Для MS SQL наверное так будет:
 SELECT t1.id ,(SELECT TOP 1 t.name FROM passenger as t WHERE t1.passenger = t.id order by t.id) as name FROM Pass_in_trip as t1 | |||
| 56
    
        bolder 29.09.22✎ 17:05 | 
        (50) Вобщем, как ожидалось.Лучше всех - в 4 раза LEFT JOIN.
 https://ibb.co/QcqWMKR | |||
| 57
    
        Said_We 29.09.22✎ 17:12 | 
        (56) Ждем четвертый вариант.     | |||
| 58
    
        bolder 29.09.22✎ 17:21 | 
        (55) То что надо! Стоимость (55) аналогична LEFT JOIN b в четыре раза лучше без соединений и INNER JOIN.
 https://ibb.co/vvvb7m3 | |||
| 59
    
        Said_We 29.09.22✎ 17:36 | 
        (58) Что и ожидалось и о чем писалось выше. Спасибо.     | |||
| 60
    
        1сПупс 03.10.22✎ 10:15 | 
        решаю задачу https://sql-academy.org/ru/trainer/tasks/18
 хочу написать так: SELECT member_name FROM FamilyMembers WHERE birthday = MIN(birthday) но пишет ошибку. Разве можно только так?: SELECT member_name FROM FamilyMembers WHERE birthday = (SELECT MIN(birthday) FROM FamilyMembers) | |||
| 61
    
        Тихий омут 03.10.22✎ 10:30 | 
        (60) select top (1) * from v8users order by v8users.Changed asc     | |||
| 62
    
        Said_We 03.10.22✎ 11:29 | 
        (60) Можно так:
 SELECT t.member_name as member_name from (SELECT member_name as member_name ,birthday as birthday ,min(birthday) over () as old_birthday FROM FamilyMembers) as t WHERE t.birthday = t.old_birthday | |||
| 63
    
        Said_We 03.10.22✎ 12:33 | 
        (60) А чем показался ваш вариант плох?
 Который вот этот: SELECT member_name FROM FamilyMembers WHERE birthday in (SELECT MIN(birthday) FROM FamilyMembers) | |||
| 64
    
        1сПупс 03.10.22✎ 13:58 | 
        (61) так можно:
 SELECT member_name FROM FamilyMembers ORDER BY birthday ASC LIMIT 1 спасибо! | |||
| 65
    
        Said_We 03.10.22✎ 14:02 | 
        (64) Нельзя. Могут быть одинакового возраста и самые старшие.     | |||
| 66
    
        1сПупс 03.10.22✎ 14:10 | 
        (65) согласен, если база на 234234 строк могут быть те, кто родился в один день.     | |||
| 67
    
        1сПупс 03.10.22✎ 14:11 | 
        (66) + просто привел вариант Тихий омут в божеский вид mssql     | |||
| 68
    
        Said_We 03.10.22✎ 14:18 | 
        (67) SQL Academy - это MySQL.
 Защиты от дурака на этом сайте нет. Можно нарисовать любой запрос, если он для единственной базы вернёт правильный результат, то и запрос будет считаться правильным. А очень часто это не так. | |||
| 69
    
        1сПупс 03.10.22✎ 18:12 | 
        (65) в задаче https://sql-academy.org/ru/trainer/tasks/23 похожие условия, нужно выбрать самые дорогие деликатесы.
 написал SELECT good_name, unit_price FROM Payments JOIN Goods ON Payments.good = Goods.good_id JOIN GoodTypes ON Goods.type = GoodTypes.good_type_id WHERE good_type_name = 'delicacies' ORDER BY unit_price DESC LIMIT 1 но понимаю что там может быть несколько деликатесов с одинаковой ценой. | |||
| 70
    
        Said_We 03.10.22✎ 18:37 | 
        (69) А если так?
 SELECT (SELECT t2.good_name FROM Goods as t2 WHERE t1.good = t2.good_id ORDER BY t2.good_id LIMIT 1 ) as good_name ,t1.unit_price as unit_price FROM (SELECT good as good ,unit_price as unit_price ,max(unit_price) over() as maxPrice FROM Payments where good in (SELECT good_id FROM Goods WHERE type in (SELECT good_type_id FROM GoodTypes WHERE good_type_name = "delicacies" ) ) ) as t1 WHERE t1.unit_price = t1.maxPrice | |||
| 71
    
        Said_We 03.10.22✎ 18:44 | 
        В первый select надо добавить ещё DISTINCT как минимум.
 А то если один и тот же деликатес продавали по максимальной цене несколько раз, то и строчек будет столько же... :-) | |||
| 72
    
        Said_We 03.10.22✎ 18:47 | 
        (69) Зачем каждый раз используешь join?
 join - это убийца производительности запросов. Его необходимо использовать и без него никак, где есть реальное соединение таблиц. А где нет соединения таблиц, то лучше не использовать. | |||
| 73
    
        1сПупс 03.10.22✎ 19:04 | 
        (70)решил сделать так, может и не правильно:
 SELECT good_name, unit_price FROM Payments JOIN Goods ON Payments.good = Goods.good_id JOIN GoodTypes ON Goods.type = GoodTypes.good_type_id WHERE good_type_name = 'delicacies' AND unit_price in ( SELECT MAX(unit_price) FROM Payments JOIN Goods ON Payments.good = Goods.good_id JOIN GoodTypes ON Goods.type = GoodTypes.good_type_id GROUP BY good_type_name HAVING good_type_name = 'delicacies' | |||
| 74
    
        Said_We 03.10.22✎ 19:07 | 
        (73) Хозяин барин. Прямо тянет на джоины, ну что тут поделаешь....
 Выполни кусок запроса и посмотри как работает "max(unit_price) over() as maxPrice" SELECT good as good ,unit_price as unit_price ,max(unit_price) over() as maxPrice FROM Payments where good in (SELECT good_id FROM Goods WHERE type in (SELECT good_type_id FROM GoodTypes WHERE good_type_name = "delicacies" ) ) | |||
| 75
    
        1сПупс 04.10.22✎ 16:41 | 
        (74) спасибо что помогаете, но пока тяжело без джунов, возможно к этому приду.
 Решаю задачу https://sql-academy.org/ru/trainer/tasks/37 SELECT FLOOR((MIN(DATEDIFF(CURRENT_TIMESTAMP(), birthday)/365))) AS year FROM Student ответ то верный, но может есть решение проще, без костылей? Для справки использую https://habr.com/ru/post/564390/#что-такое-sql | |||
| 76
    
        mistеr 04.10.22✎ 16:56 | 
        (72) Джойны это основа основ реляционных БД.
 А убийцы производительности это кривые руки и каша в голове. | |||
| 77
    
        mistеr 04.10.22✎ 17:04 | 
        (75) Нормальное решение. Упростить можно только DATEDIFF(CURRENT_TIMESTAMP(), MAX(birthday))     | |||
| 78
    
        Said_We 04.10.22✎ 19:12 | 
        (76) Не внимательно читаете. Третью строчку не читали или решили остановится на второй? :-)     | |||
| 79
    
        1сПупс 04.10.22✎ 20:30 | 
        делаю задачу https://sql-academy.org/ru/trainer/tasks/49
 сделал запрос: ученики класса 10а: SELECT COUNT(*) FROM Student JOIN Student_in_class ON Student.id = Student_in_class.student JOIN Class ON Class.id = Student_in_class.class WHERE name = '10 A' все ученики: SELECT COUNT(*) FROM Student JOIN Student_in_class ON Student.id = Student_in_class.student JOIN Class ON Class.id = Student_in_class.class Хотелось бы результат запроса 1 передать в переменную 1, а потом результат запроса 2 передать в переменную 2, а потом одно разделить на другое. Как это можно сделать? Или задача решается по другому? | |||
| 80
    
        mistеr 04.10.22✎ 21:38 | 
        (79) Используй левое соединение Student к Student_in_class с условием класс только 10А.
 По этой выборке ты сможешь сразу подсчитать и общее количество и в этом классе, и разделить. | |||
| 81
    
        Мультук гуру 04.10.22✎ 22:01 | 
        (79) 
 SELECT count (case when class.name = '10 A' then Student_in_class.student else null end) / count (Student_in_class.student) * 100 as percent FROM Student_in_class left JOIN Class ON Class.id = Student_in_class.class P.S. Left - потому что в этом странном заведении в таблице Student_in_class есть записи с "class", которых нет в таблице class | |||
| 82
    
        mistеr 04.10.22✎ 22:09 | 
        (81) Теоретически студент может участвовать в нескольких классах.     | |||
| 83
    
        Мультук гуру 04.10.22✎ 22:16 | 
        (82) 
 Я о ситуации, когда запрос возвращает строки. SELECT Student_in_class.id, Student_in_class.class, class.name FROM Student_in_class left JOIN Class ON Class.id = Student_in_class.class where Class.id is null | |||
| 84
    
        mistеr 04.10.22✎ 22:19 | 
        (83) Я понял. А я о том, что соединение нужно в другую сторону.     | |||
| 85
    
        1сПупс 06.10.22✎ 13:47 | 
        Делаю задачу https://sql-academy.org/ru/trainer/tasks/60
 решил, но долго думал можно ли тут использовать группировку вроде этого: SELECT DISTINCT teacher, FROM Schedule JOIN Class ON Schedule.class = Class.id WHERE name LIKE '11%' GROUP BY teacher, name HAVING COUNT(*)>1 ORDER BY name, teacher вот решение без группировки: SELECT DISTINCT teacher FROM Schedule JOIN Class ON Schedule.class = Class.id WHERE teacher IN ( SELECT teacher FROM Schedule JOIN Class ON Schedule.class = Class.id WHERE name = '11 A' ) AND teacher IN ( SELECT teacher FROM Schedule JOIN Class ON Schedule.class = Class.id WHERE name = '11 B') | |||
| 86
    
        Said_We 06.10.22✎ 14:01 | 
        (85) С формулировкой там всё нормально?
 "Выведите идентификаторы преподавателей, которые хотя бы один раз за всё время преподавали в КАЖДОМ из одиннадцатых классов.". Не увидел поиска полного количества 11-х классов, которое потом сравнивается с количеством классов 11-х, по каждому учителю в которых он преподавал. | |||
| 87
    
        Said_We 06.10.22✎ 14:41 | 
        (85) В решении в (85) прописаны жестко 11 А и 11 Б. А если вдруг будет 11 Г, то запрос перестанет работать?     | |||
| 88
    
        Мультук гуру 06.10.22✎ 14:50 | 
        (85) 
 1) Зачем тут ORDER by -- что он делает полезного 2) HAVING COUNT(*) = Запрос{Количество 11 классов} | |||
| 89
    
        Мультук гуру 06.10.22✎ 14:59 | 
        (85) 
 И еще подсказка having count(*) Вместо * можно написать имя поля или distinct ИмяПоля | |||
| 90
    
        Said_We 06.10.22✎ 15:15 | 
        (85)
 Можно и так: WITH Klass_11 as (SELECT id as id FROM class WHERE name LIKE "11%") ,kol_11 as (SELECT COUNT(id) as kol FROM Klass_11) SELECT t.teacher FROM (SELECT t.teacher ,COUNT(t.class) as kol FROM (SELECT DISTINCT teacher ,class from Schedule WHERE class in (SELECT id from Klass_11) ) as t GROUP BY t.teacher ) as t WHERE t.kol in (SELECT t1.kol FROM kol_11 as t1) | |||
| 91
    
        Мультук гуру 06.10.22✎ 15:34 | 
        (90) 
 select schedule.teacher from schedule join class on schedule.class = class.id where class.name like '11%' group by schedule.teacher having count(DISTINCT schedule.class) = (select count(id) from class where name like '11%') | |||
| 92
    
        Said_We 06.10.22✎ 16:03 | 
        (91) join, то тут зачем?
 В schedule уже есть класс. На него только условие необходимо наложить. WHERE class in (SELECT id as id FROM class WHERE name LIKE "11%") Таблицы тут связывать не к чему на мой взгляд. Тем более вместо условия после связи <where class.name like '11%'>, если уж решили в обязательном порядке использовать джоин, то логичнее вторую таблицу предварительно обрезать как раз этим условием. т.е. до джоина. | |||
| 93
    
        Мультук гуру 06.10.22✎ 16:14 | 
        (92) 
 1) Т.е. join это всегда плохо, а in - всегда хорошо ? Много лет назад меня учили ровно до-наборот Правда это был не MS-SQL, а Interbase/Firebird 2) У меня сейчас нет возможности смотреть насколько сильно повлияет на план запроса перетаскивание условия select schedule.teacher from schedule join class on schedule.class = class.id and class.name like '11%' | |||
| 94
    
        Said_We 06.10.22✎ 16:24 | 
        (93) Можно и как ниже. Но тут есть копи паст в виде <FROM class WHERE name LIKE "11%">
 SELECT t.teacher FROM (SELECT teacher ,DENSE_RANK() over (partition by teacher ORDER by teacher, class) as r from Schedule WHERE class in (SELECT id as id FROM class WHERE name LIKE "11%") ) as t GROUP BY t.teacher HAVING max(t.r) = (SELECT COUNT(id) as id FROM class WHERE name LIKE "11%") (93) А что тут гадать про данный случай. В результате всего несколько 11 классов. Или их количество всегда одна строчка. Это условие на очень ограниченное количество значений. IN тут и более читабелен и по скорости уж точно медленнее не будет. | |||
| 95
    
        Said_We 06.10.22✎ 17:13 | 
        (93) Такая связь:
 select schedule.teacher from schedule join class on schedule.class = class.id and class.name like '11%' Точно хуже такой: select schedule.teacher from schedule join (select id from class where name like '11%') as t2 on schedule.class = t2.id Зачем связывать со всеми классами и потом накладывать условия только на классы, когда можно сразу связывать с уже ограниченным количеством классов. Таблица изначально уже меньше. Решение в (90) более прозрачное и легко читаемое. Решение в (94) по сути тоже самое, но менее понятным языком. | |||
| 96
    
        Said_We 09.10.22✎ 23:57 | 
        (0) Все задачи уже сделал?     | |||
| 97
    
        Said_We 10.10.22✎ 16:44 | 
        Скорее всего уже все сделал.
 Хоть впечатлениями бы поделился. | |||
| 98
    
        1сПупс 10.10.22✎ 19:09 | 
        (96) решаю задачу  https://sql-academy.org/ru/trainer/tasks/68
 Впечатления такие, что будто заново изобретаю велосипед. Получаю комнаты и даты выезда очень просто, только не могу понять как сюда припаять user_id: SELECT room_id, MAX(end_date) as end_date FROM Reservations GROUP BY room_id Сделал так, но по-моему это слишком заумно, поправьте если не прав. SELECT V.room_id, name, V.end_date FROM ( SELECT room_id, MAX(end_date) as end_date FROM Reservations GROUP BY room_id) as V JOIN Reservations ON V.end_date = Reservations.end_date AND V.room_id = Reservations.room_id JOIN Users ON Reservations.user_id = Users.id | |||
| 99
    
        mistеr 10.10.22✎ 20:40 | 
        (98) Все верно, только я бы ориентировался на на end_date, а на start_date при поиске последней брони.     | |||
| 100
    
        Said_We 10.10.22✎ 21:44 | 
        (98) А если так?
 SELECT t.room_id ,(SELECT name FROM Users as t1 WHERE t.user_id = t1.id) as name ,end_date from (SELECT row_number() over(partition by room_id order by end_date DESC) as npp ,room_id ,user_id ,end_date FROM Reservations ) as t WHERE t.npp = 1 | |||
| 101
    
        Said_We 10.10.22✎ 22:01 | 
        Если совсем правильно, то после:
 WHERE t.user_id = t1.id должен быть ещё и LIMIT: LIMIT 1 ) as name Но версия MYSQL, которая проверяет "хавает" и так, так как user_id вторичный ключ и id первичный ключ. Более ранние версии могут в ошибку уходить. | |||
| 102
    
        Said_We 10.10.22✎ 22:05 | 
        (99) Зачем ориентироваться на дату заезда? Какая разница когда постоялец въехал, важно когда выехал и то, что он последний.     | |||
| 103
    
        Said_We 10.10.22✎ 22:07 | 
        (98) "Впечатления такие, что будто заново изобретаю велосипед." - это нормальные впечатления.
 Голова должна просто перестроится и усё. Это практика и время. У всех по разному с точки зрения времени. Но так же как с велосипедом - один раз научишься и более не разучишься. | |||
| 104
    
        mistеr 11.10.22✎ 09:47 | 
        (102) При нормальном проектировании там будет констрейнт уникальности (user_id, start_date), что позволяет не думать о дублях, да и слегка побыстрее будет, скорее всего. Но это уже за рамками задачи.     | |||
| 105
    
        Said_We 11.10.22✎ 10:14 | 
        (104) Ничего не понял из сказанного.
 Номера могут быть с подселением. Поэтому не важно последний он в номер заехал или первый. Важно кто последний выехал, так как именно это спрашивается из задания. Более того на сейчас могут быть заехавшие и ещё не выехавшие и проживающие. По заданию они нас не интересуют. | |||
| 106
    
        mistеr 11.10.22✎ 10:39 | 
        (105) "person who last rented it" это тот кто последний въехал/забронировал.
 Причем тут подселение, не понял. Даже если возможно, по-моему, это ничего не меняет. | |||
| 107
    
        1сПупс 11.10.22✎ 10:43 | 
        (105) все прорешал, всем спасибо за помощь, оссобенно Said_We
 Впечатление хорошее, полезный ресурс. Для себя открыл несколько ресурсов для справки: https://oracleplsql.ru/mysql-manual.html http://www.sql-tutorial.ru/ru/content.html https://habr.com/ru/post/564390/ | |||
| 108
    
        Said_We 11.10.22✎ 10:44 | 
        (106) Я не читал английский вариант задания. По русски он выглядит так:
 "#68 Для каждой комнаты, которую снимали как минимум 1 раз, найдите имя человека, снимавшего ее последний раз, и дату, когда он выехал". | |||
| 109
    
        Said_We 11.10.22✎ 10:48 | 
        (106) "Причем тут подселение, не понял. Даже если возможно, по-моему, это ничего не меняет."
 Ну как же не меняет? Представь вариант. Комната ФИО ДатаН ДатаК 1 Иванов И.И. 01.01.2022 31.01.2022 1 Петров С.О. 06.01.2022 15.01.2022 | |||
| 110
    
        mistеr 11.10.22✎ 11:35 | 
        (109) Последним снял Петров, выехал 15-го.     | |||
| 111
    
        Said_We 11.10.22✎ 12:12 | 
        (110) Последним снимал и выехал Иванов, так как он ещё две недели жил в номере, после того как Петров из номера выехал.     | |||
| 112
    
        Said_We 11.10.22✎ 12:14 | 
        (110) Автор закончил курс SQL Academy в части select, о чем написал в (107). Ветку можно закрывать.
 (107) Не за что. | 
| Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |