Если вы хотите, чтобы столбец, возвращаемый второго запроса, чтобы быть добавил результатам первого запроса, вы можете просто включить свой второй запрос в первой, как коррелировала подзапрос, как это :
SELECT
XEDETALLES_BODEGA.IDPROD,
SUM(XEDETALLES_BODEGA.CANTIDAD) AS CANTIDAD,
MONTH(XEDETALLES_BODEGA.XFECHA) AS MES,
YEAR(XEDETALLES_BODEGA.XFECHA) AS ANO,
CONVERT(DATETIME, CAST(YEAR(XEDETALLES_BODEGA.XFECHA) AS VARCHAR) + '-1-' + CAST(MONTH(XEDETALLES_BODEGA.XFECHA) AS VARCHAR), 103) AS FECHA,
( SELECT TOP (1) PRECIOUNIT FROM XCDETALLES_BODEGA WHERE (XCDETALLES_BODEGA.IDPROD = XEDETALLES_BODEGA.IDPROD) AND (XCDETALLES_BODEGA.XFECHA < CONVERT(DATETIME, CAST(YEAR(XEDETALLES_BODEGA.XFECHA) AS VARCHAR) + '-1-' + CAST(MONTH(XEDETALLES_BODEGA.XFECHA) AS VARCHAR), 103)) ORDER BY XCDETALLES_BODEGA.XFECHA DESC ) AS PRECIOUNIT
FROM XEDETALLES_BODEGA
LEFT OUTER JOIN xEGRESOS_BODEGA ON XEDETALLES_BODEGA.IDEGRESO = xEGRESOS_BODEGA.ID
WHERE (YEAR(XEDETALLES_BODEGA.XFECHA) = 2012) AND XEDETALLES_BODEGA.IDPROD <> 0
GROUP BY XEDETALLES_BODEGA.IDPROD, MONTH(XEDETALLES_BODEGA.XFECHA), YEAR(XEDETALLES_BODEGA.XFECHA)
ORDER BY XEDETALLES_BODEGA.IDPROD, MONTH(XEDETALLES_BODEGA.XFECHA), YEAR(XEDETALLES_BODEGA.XFECHA)
;
Однако в этом вопросе есть возможности для улучшения.
Прежде всего, я бы представил более короткие псевдонимы таблиц. Просто подумайте над этим переписанием:
SELECT
xed.IDPROD,
SUM(xed.CANTIDAD) AS CANTIDAD,
MONTH(xed.XFECHA) AS MES,
YEAR(xed.XFECHA) AS ANO,
CONVERT(DATETIME, CAST(YEAR(xed.XFECHA) AS VARCHAR) + '-1-' + CAST(MONTH(xed.XFECHA) AS VARCHAR), 103) AS FECHA,
(
SELECT TOP (1) PRECIOUNIT
FROM XCDETALLES_BODEGA AS xcd
WHERE (xcd.IDPROD = xed.IDPROD)
AND (xcd.XFECHA < CONVERT(DATETIME, CAST(YEAR(xed.XFECHA) AS VARCHAR) + '-1-' + CAST(MONTH(xed.XFECHA) AS VARCHAR), 103))
ORDER BY xcdXFECHA DESC
) AS PRECIOUNIT
FROM XEDETALLES_BODEGA AS xed
LEFT OUTER JOIN xEGRESOS_BODEGA AS xeg ON xed.IDEGRESO = xeg.ID
WHERE (YEAR(xed.XFECHA) = 2012) AND xed.IDPROD <> 0
GROUP BY xed.IDPROD, MONTH(xed.XFECHA), YEAR(xed.XFECHA)
ORDER BY xed.IDPROD, MONTH(xed.XFECHA), YEAR(xed.XFECHA)
;
Согласны ли вы с тем, что более короткие псевдонимы делают ваш запрос более удобочитаемым?
Другой проблемой является ваши критерии группировки, в частности, эти два пункта:
MONTH(xed.XFECHA), YEAR(xed.XFECHA)
Они, конечно, сделать ваши намерения ясны, но они также испытывают множественные преобразования, как вы делаете их обратно в значение datetime
. И теперь мы также используем тот же datetime
в коррелированном подзапросе. Эти преобразования абсолютно не нужны, потому что вы можете обойти это наоборот. Вместо того, чтобы извлекать год и месяц из datetime
, а затем преобразовать их обратно в datetime
, вы можете «округлить» дату и время до начала соответствующего месяца. Следующее выражение делает только что:
DATEADD(MONTH, DATEDIFF(MONTH, 0, xed.XFECHA), 0)
Теперь, когда вам нужно отобразить месяц и год, как числовые значения, вы можете извлечь их из результата приведенного выше выражения, так как это даст вам тот же самый месяц и год. Итак, взгляните на ваш запрос сейчас:
SELECT
xed.IDPROD,
SUM(xed.CANTIDAD) AS CANTIDAD,
MONTH(DATEADD(MONTH, DATEDIFF(MONTH, 0, xed.XFECHA), 0)) AS MES,
YEAR(DATEADD(MONTH, DATEDIFF(MONTH, 0, xed.XFECHA), 0)) AS ANO,
DATEADD(MONTH, DATEDIFF(MONTH, 0, xed.XFECHA), 0) AS FECHA,
(
SELECT TOP (1) PRECIOUNIT
FROM XCDETALLES_BODEGA AS xcd
WHERE (xcd.IDPROD = xed.IDPROD)
AND (xcd.XFECHA < DATEADD(MONTH, DATEDIFF(MONTH, 0, xed.XFECHA), 0))
ORDER BY xcd.XFECHA DESC
) AS PRECIOUNIT
FROM XEDETALLES_BODEGA AS xed
LEFT OUTER JOIN xEGRESOS_BODEGA AS xeg ON xed.IDEGRESO = xeg.ID
WHERE (YEAR(xed.XFECHA) = 2012) AND xed.IDPROD <> 0
GROUP BY xed.IDPROD, DATEADD(MONTH, DATEDIFF(MONTH, 0, xed.XFECHA), 0)
ORDER BY xed.IDPROD, DATEADD(MONTH, DATEDIFF(MONTH, 0, xed.XFECHA), 0)
;
Я знаю, о чем вы думаете. Новое выражение, кажется, используется слишком много раз, что не делает запрос очень чистым, тем более, что выражение не так коротки. Может ли это помочь? Да, оно может. Вы можете использовать производную таблицу. Поместите соединения, фильтр WHERE и необходимые столбцы, включая выражение, вычисляющее начало месяца, в подзапрос и пусть ваш основной запрос вытащит данные из него. Оставьте группировку, сортировку и коррелированный подзапрос в главном SELECT. Короче говоря, это то, что вы могли бы в конечном итоге с:
SELECT
s.IDPROD,
SUM(s.CANTIDAD) AS CANTIDAD,
MONTH(s.XFECHA) AS MES,
YEAR(s.XFECHA) AS ANO,
s.XFECHA,
(
SELECT TOP (1) PRECIOUNIT
FROM XCDETALLES_BODEGA AS xcd
WHERE (xcd.IDPROD = xed.IDPROD)
AND (xcd.XFECHA < s.XFECHA
ORDER BY xcd.XFECHA DESC
) AS PRECIOUNIT
FROM ( SELECT xed.IDPROD, xed.CANTIDAD, DATEADD(MONTH, DATEDIFF(MONTH, 0, xed.XFECHA), 0) AS FECHA FROM XEDETALLES_BODEGA AS xed LEFT OUTER JOIN xEGRESOS_BODEGA AS xeg ON xed.IDEGRESO = xeg.ID WHERE (YEAR(xed.XFECHA) = 2012) AND xed.IDPROD <> 0 ) s
GROUP BY s.IDPROD, s.XFECHA
ORDER BY s.IDPROD, s.XFECHA
;
Однако, если вы используете SQL Server 2005 или более поздней версии, вам не нужно производной таблицы - вы можете использовать CROSS ОТНОСИТЬСЯ вместо.Здесь:
SELECT
xed.IDPROD
SUM(xed.CANTIDAD) AS CANTIDAD,
MONTH(s.XFECHA) AS MES,
YEAR(s.XFECHA) AS ANO,
s.XFECHA,
(
SELECT TOP (1) PRECIOUNIT
FROM XCDETALLES_BODEGA AS xcd
WHERE (xcd.IDPROD = xed.IDPROD)
AND (xcd.XFECHA < s.XFECHA
ORDER BY xcd.XFECHA DESC
) AS PRECIOUNIT
FROM XEDETALLES_BODEGA AS xed
LEFT OUTER JOIN xEGRESOS_BODEGA AS xeg ON xed.IDEGRESO = xeg.ID
CROSS APPLY ( SELECT DATEADD(MONTH, DATEDIFF(MONTH, 0, xed.XFECHA), 0) AS FECHA ) AS s
WHERE (YEAR(xed.XFECHA) = 2012) AND xed.IDPROD <> 0
GROUP BY xed.IDPROD, s.XFECHA
ORDER BY xed.IDPROD, s.XFECHA
;
Измените свой ответ, чтобы удалить ВСЕ CAPS, и используйте редактор кода для форматирования своего кода, чтобы он был читабельным. Верните свой реальный вопрос, чтобы было ясно, что вы просите. –