[SQL] нюбский вопрос
ps да, и еще напиши, пожалуйста, запрос как можно более точно - мне что-то кажется, что написанное при любом "(подзапросе)" работать не будет
з.ы. а используя только стандарт .92 никак?
я не готов отвечать по мускулю, по 2005 - посмотри, я там пост обновил примерно в одно время с твоим ответом
на самом деле проблема не первый раз возникает (я обобщил поэтому хотелось бы решение при условии сферического коня в вакууме.
А твой сферический запрос работать точно не будет в 2005 , можешь подставить (select 1,2,3,4) as T(p1,p2,p3,p4) и попробовать
или подразумевается это:
SELECT p1,p2,p3,
SELECT SUM(p4) FROM (подзапрос1) AS t2 WHERE t2.p4 < t1.p4
FROM (подзапрос1) AS t1
SELECT t1.p1,t1.p2,t1.p3, sum(t2.p4)
FROM (подзапрос1) AS t1, (подзапрос2) AS t2
where t2.p4<t1.p4
group by t1.*
или я неверно понял задачу
ну вот я подумал на select ... , (select sum ...) from ..., однако такой вариант тоже был - поэтому и попросил уточнить
как упростить конструкцию (подзапрос очень громоздкий чтобы подзапрос выполнялся один раздаже если "(подзапрос)" будет тупо скопипищен в два места, он вряд ли будет выполняться два раза — сиквел сервер умный . SQL запрос это всего лишь запись того, что ты хочешь получить в результате, как это получить сиквел сервер решает сам (если хинты не использовать, их не рекомендуют использовать). Посмотри план запроса.
То есть проблема только в том, что не хорошо копипастить код подзапроса. По моим сведениям, в SQL92 копипаста можно избежать только через виьюхи, но это не всегда удобно. В MSSQL2005 для твоего случая подойдут Common Table Expressions (оператор WITH перед SELECT).
ну да, это если подзапросы никак не связаны
ну тут можно сказать про скалярные функции, которые даже будучи написанными всего лишь раз будут дергаться постоянно, что сильно снижает производительность, даже если там идет тупо число+1
В ответ на:эти запросы не эквивалентны, например, второй возвратит пустое множество на таблице из одной строки, а первый нет.
code:
SELECT p1,p2,p3,
SELECT SUM(p4) FROM (подзапрос1) AS t2 WHERE t2.p4 < t1.p4
FROM (подзапрос1) AS t1
или подразумевается это:
code:
SELECT t1.p1,t1.p2,t1.p3, sum(t2.p4)
FROM (подзапрос1) AS t1, (подзапрос2) AS t2
where t2.p4<t1.p4
group by t1.*
ну тут можно сказать про скалярные функции, которые даже будучи написанными всего лишь раз будут дергаться постоянно, что сильно снижает производительность, даже если там идет тупо число+1ну тк если речь об этом, то причем тут подзапрос? эта проблема и на просто таблице будет. Я так понял, в первом посте основной упор был на проблему громоздкого подзапроса.
Оконной функции, по моему, такой нет.
эти запросы не эквивалентны, например, второй возвратит пустое множество на таблице из одной строки, а первый нет.тупанул, да. Надо left join
или подразумевается это:так нельзя - у тебя в group by и в конечной выборке разное количество полей.
code:
SELECT t1.p1,t1.p2,t1.p3, sum(t2.p4)
FROM (подзапрос1) AS t1, (подзапрос2) AS t2
where t2.p4<t1.p4
group by t1.*
а должно быть одинаковое, потому что аггрегирующие функции уменьшают детализацию.
а в оконную функцию ты условие t2.p4<t1.p4 не сможешь запихать
в общем твой запрос работать не будет
так нельзя - у тебя в group by и в конечной выборке разное количество полей.а должно быть одинаковоеlol what? Это неверно. Верно такое утверждение:
если поле стоит в выборке без агрегатных функций, то оно должно быть упомянуто в group by
и то mysql-щики такое разрешают, выдавая одно из многих, вообще говоря, значений
спасибо просто огромное за WITH - совсем забыл про эту фичу
Оконной функции, по моему, такой нет.угу, к сожалению нет. а было бы прикольно накладывать окно для аггрегации к строке по буленовскому выражению скажем.
Ну я просто не стал бы однозначно говорить, что подзапрос будет выполняться один раз. Оконных функций таких (если опять таки нарастающий итог иметь в виду) - в 2005 нету (однако вроде как в стандарте в оракле работает. А СТЕ в принципе можно и рекурсивно использовать для этой задачи, не только как способ минимизации громоздкого запроса (хотя изврат на мой взгляд)
а первый работает?
конечно работает.
/*------------------------
SELECT p1,p2,p3,
SELECT SUM(p4) FROM (select 1 p1, 2 p2, 3 p3, 4 p4) AS t2 WHERE t2.p4 < t1.p4
FROM (select 1 p1, 2 p2, 3 p3, 4 p4) AS t1
------------------------*/
Msg 156, Level 15, State 1, Line 2
Incorrect syntax near the keyword 'SELECT'.
Msg 156, Level 15, State 1, Line 3
Incorrect syntax near the keyword 'FROM'.
Msg 156, Level 15, State 1, Line 3
Incorrect syntax near the keyword 'AS'.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 1 ms.
ладно, тебе виднее наверное, как обмануть сервер
Если в мускуле работает - ну, там много что есть непонятного
/*------------------------
SELECT t1.p1,t1.p2,t1.p3, sum(t2.p4)
FROM (select 1 p1, 2 p2, 3 p3, 4 p4) AS t1, (select 1 p1, 2 p2, 3 p3, 4 p4) AS t2
where t2.p4<t1.p4
group by t1.p1,t1.p2,t1.p3
------------------------*/
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 3 ms.
p1 p2 p3
----------- ----------- ----------- -----------
(0 row(s) affected)
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 1 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 1 ms.
SELECT p1,p2,p3,
(
SELECT SUM(p4) FROM (select 1 p1, 2 p2, 3 p3, 4 p4) AS t2
WHERE t2.p4 < t1.p4
) AS t4sum
FROM (select 1 p1, 2 p2, 3 p3, 4 p4) AS t1
----------------
p1 p2 p3 t4sum
1 2 3 NULL
а что тогда сразу поточнее запрос не написал, вроде просил? ну и то, что первый запрос работает, а второй нет вроде как не я писал
SELECT p1,p2,p3, SELECT SUM(t1.p4) OVER (ORDER BY t1.p4 RANGE BETWEEN UNBOUNDED PRECEDING AND 1 preceding)
FROM (подзапрос) AS t1
Судя по google и MySQL и SQL/2005 это умеют.
P.s. Писалось по синтаксису Oracle, т.ч. возможны ошибки
UPD: Нет, не умеют, а жаль.
К сожалению, Шурик, в 2005 агрегатные функции над окнами поддерживают только PARTITION BY
Оставить комментарий
kill-still
T-SQLесть таблица, в которой несколько столбцов подготавливается в подзапросах
нужно создать ещё один столбец, в котором будет сумма значений полей одного из имеющихся столбцов, не превышающих по значению поле этого же столбца в вычисляемой строчке.
как упростить конструкцию (подзапрос очень громоздкий чтобы подзапрос выполнялся один раз