SELECT (to_char(date_trunc('day',DOC.registrationdate),'dd.MM.yyyy')) AS dateOfDoc, sum(case when DOC.doc_type_id=301 then DOC.sum when DOC.doc_type_id=303 then -DOC.sum else 0 end) AS cashReceiptsAll, sum(case when DOC.doc_type_id=301 AND DOCFIS.payment_method_id=1 then DOC.sum else 0 end) AS cash, sum(case when DOC.doc_type_id=301 AND DOCFIS.payment_method_id=2 then DOC.sum else 0 end) AS cashReceiptsCards, sum(case when DOC.doc_type_id=301 AND DOCFIS.payment_system_id=11 then DOC.sum else 0 end) AS cashReceiptsMalina, sum(case when DOC.doc_type_id=302 then DOC.sum else 0 end) AS cashReceiptsMobilePayments, (SELECT sum(accountingsum) FROM documents innerDOC1 WHERE innerDOC1.registrationdate IN (SELECT (SELECT max(registrationdate) FROM documents innerDOC2 WHERE to_number(innerDOC2.description,'999999999') = CR.number AND innerDOC2.doc_type_id=401 AND innerDOC2.registrationdate < date_trunc('day',DOC.registrationdate) ) FROM cash_register AS CR JOIN remains_area RA ON CR.area_id = RA.remains_area_id WHERE RA.placement_id=3310568) ) AS balanceStartDay FROM documents DOC JOIN documents_fiscals DOCFIS ON DOC.document_id = DOCFIS.doc_fiscal_id WHERE DOC.registrationDate >= date_trunc('day',date(('2012-01-01'))) AND DOC.registrationDate<=to_timestamp(to_char(date(('2012.03.18')),'dd-mm-yyyy')||' 23:59:59','DD-MM-YYYY HH24:MI:SS') GROUP BY date_trunc('day',DOC.registrationdate) ORDER BY date_trunc('day',DOC.registrationdate);
Валится с ошибкой : ERROR: subquery uses ungrouped column "doc.registrationdate" from outer query
я так понимаю ругается на фрагмент в подзапросе "innerDOC2.registrationdate < date_trunc('day',DOC.registrationdate)", но я не знаю как его переписать иначе. Подскажите есть ли возможность иначе выполнить, я могу ошибаться, но в оракле это отрабатывает нормально.
Вот знаете, честно, даже
Вот знаете, честно, даже разбираться не хочу, посмотрев, что у вас АЖ ТРИ вложенных подзапроса.
Я являюсь администратором хостинга и знаю как такие запросы работают - по принципу: "убей сервер нахрен".
Поэтому переписывайте ваш запрос, избавляясь от subSELECT'ов, тогда и ошибка исчезнет. Знаю, что не всегда возможно избавится от подзапросов совсем, но хотя бы один, а не три, а кроме того, иногда бывает намного быстрее разбить запрос на подзапросы, чем городить что-то невообразимое.
Данный запрос реализует
Данный запрос реализует выборку для отчёта, посему разбить его на под запросы не является возможным. Далее. Подзапросы ИМХО работают эффективнее чем перемножение одной и той же таблицы по 3 - 4 раза. Ну не хотите... Спасибо и на этом.
ПС: Не хотите разбираться, однако на каком- то мистическом основании утверждаете "переписывайте без сабселектов и ошибка исправится"... а потом напишите "что не исправилас да? а ну ладно, тогда не знаю" ))) gg
> Данный запрос реализует
> Данный запрос реализует выборку для отчёта, посему разбить его на под запросы не является возможным
всё возможно. любые НОРМАЛЬНЫЕ средства генерации отчётов позволяют работать с группой запросов, а не одним. Даже если у вас ненормальное средство генерации отчётов, никто не мешает засунуть несколько запросов в хранимую процедуру и вызывать её одним SELECT'ом. Так, что дело не в отчёте, а в вашем желании. Если вы хотите измудриться и сделать всё за раз - ваше право, но тогда ломайте голову чего у вас не работает сами
> ПС: Не хотите разбираться, однако на каком- то мистическом основании утверждаете "переписывайте без сабселектов и ошибка исправится"... а потом напишите "что не исправилас да? а ну ладно, тогда не знаю" ))) gg
Мистическое основание назвается "опыт работы". По своему опыту работы знаю, что стоит дать хорошего пинка под зад программисту и вдруг волшебным образом запросы начинают работать и в 10-100 раз быстрее при этом совершенно не нагружая сервер. Вот такие чудеса случаются, мистические
Можно написать и хранимую
Можно написать и хранимую процедуру, можно и для каждого отчёта по 10 хранимых процедур писать, а затем нанимать ещё 2 SQL разработчика, в довесок ява программистам, что бы они отдельно вели базу данных. Не спорю - написать хранимку и использовать её в запросе это эффективно, но это требует более высокой специализации в области SQL и размазывает логику программы по базе данных. Отладка становится в разы сложнее, потому что надо не только дебажить программу, но и одновременно с этим выполнение процедуры в базе данных, что влечёт за собой усложнение сопровеждения ПО. Не спорю пинка можно дать каждому и он изъебнётся и сделает ассемблерные вставки, напишет собственный модуль к драйверу, вопрос - а нахуя?
В общем вижу демогогию вы разводите великолепно, даёте указаниия здоровски, а приложить свой ум к фактическому назначению данного форума (ответы на вопросы и помощь) у вас не хватает желания. Мы можем и дальше флейм разводить, но вопроса это не решит.
ПС: От чего не прокомментировали моё утверждение о том что подзапросы работают быстрее чем перемножение одной таблицы по 3 раза? От того что это действительно так?
> Но это требует более
> Но это требует более высокой специализации в области SQL и размазывает логику программы по базе данных.
Ой, да перестаньте. Судя по этому запросу нет там никакой "высокой специализации", ничего особенного. Что касается размазывания логики, то вы программу делаете для логики или для того, чтобы получить результат? Если первое, больше вопросов нет.
> Отладка становится в разы сложнее, потому что надо не только дебажить программу,
А по-моему наоборот! Вы описываете ОДИН РАЗ для программы, что на входе и что на выходе, отлаживаете и больше не возвращаетесь к этому. Затем внутри БД вы можете менять структуру, таблицы, менять запросы, практически делать что хотите при условии, что ваша хранимая процедура по-прежнему получает тот же самый набор аргументов и выдаёт тот же самый набор полей. Вот это НАМНОГО удобней, чем переписывать каждый раз программу, если понадобится что-то доправить в запросах или таблицах.
> В общем вижу демогогию вы разводите великолепно, даёте указаниия здоровски, а приложить свой ум к фактическому назначению данного форума (ответы на вопросы и помощь) у вас не хватает желания.
Ага. Вы правильно меня поняли. Могу даже пояснить почему.
Обычно люди приводят структуру таблиц, даже прикрепляют дамп с тестовыми данными и говорят - хочу получить вот это - как? А вы предлагаете задачу в стиле: "я тут понамудрил три вложенных SELECT'а, что мне нужно гадайте сами, структуру БД тоже домысливайте самостоятельно, данные для отладки тоже набивайте сами - меня ломает, а теперь скажите чего у меня тут не работает?"
> ПС: От чего не прокомментировали моё утверждение о том что подзапросы работают быстрее чем перемножение одной таблицы по 3 раза? От того что это действительно так?
Смотря какие подзапросы. Я план вашего запроса не строил, индексов и стуктуры вашей БД не знаю. Обычно подзапрос как раз медленее, но как уже сказано разные запросы бывают и подзапросы тоже.
поддерживаю admin-а в том,
поддерживаю admin-а в том, что было бы не плохо структуру таблиц и текстовое отображение данных, необходимых для выполнения запроса.
с другой стороны, сам использую вложенные подзапросы. Но в postgresql есть очень удобное средство для организации вложенных подзапросов: инструкция with. С помощью нее можно все используемые подзапросы выделить в отдельную часть и затем использовать в итоговом запросе альясы этих подзапросов. Очень сильно упрощает написание сложных и очень сложных запросов (у меня некоторые насчитывают тысячи строк).
Нисколько не хочу умалить
Нисколько не хочу умалить значимость и ценность подзапросов, но в своей практике очень часто сталкивался с ситуациями, когда подзапросы используют совершенно неграмотно там, где они совершенно не нужны. Если бы люди посидели и подумали, то вполне возможно нашли бы способ отказаться от их использования (не всегда, конечно, это возможно, но всё же).
Не замерял как в PostgreSQL, а в MySQL подзапросы часто не оптимизируются вовсе и тогда на сервере такая бомба получается, что мама не горюй.
Думаю ошибка происходит
Думаю ошибка происходит потому, что в строке "innerDOC2.registrationdate < date_trunc('day',DOC.registrationdate" идет обращение к DOC.registrationdate из главного запроса, которое модифицированно..., а точнее причина ошибки в том что вы обращаетесь не к чистому значению DOC.registrationdate, а к модифицированному функций date_trunc() (в секции group by). Попробуйте убрать эту модификацию (из group by) и все должно работать.
А по-поводу самого запроса, я частично поддержу коллег, которые ранее тут отписывались... Я бы посоветовал его оптимизировать. Но, конечно же, это личное дело каждого.