Я написал следующий запрос, чтобы извлечь стоимость единицы из другой таблицы COSreport
в свой запрос прибыльности ProfitabilityReport
, и у меня возникла проблема с моим подзапросом.
select
i.tranid
, it.item_id
, it.displayname
, tl.Item_Count * -1 Unit_Qty
, case when tl.Item_Count=0 then 0
else ((tl.GROSS_AMOUNT * -1)/ Item_Count) * -1
end as PricePerUnit,
**(select sum(c.tranamt) from ns.COSreport c
inner join ns.ProfitabilityReport d
on c.InvoiceID = d.tranid
and c.item_id = d.item_id) as 'True Cost'**
, '0' 'Cost Per M'
from ns.tinvoice i
join ns.transaction_lines tl on i.transaction_id = tl.transaction_id
join ns.Customers cust on c.customer_id = i.ENTITY_ID
join ns.items it on it.item_id = tl.item_id
left join ns.ITEM_CLASSIFICATION it_class on it_class.list_id =
it.ITEM_CLASSIFICATION_ID
where list_item_name IS NOT NULL
and i.tranid = '1262INV'
Я присоединяюсь как к invoice id
, так и к item id
, так что правильная стоимость рассчитывается для данного счета и товара из COSReport
.
Однако истинная стоимость не сводится к стоимости единицы, а вместо этого суммируется в поле стоимости для всей таблицы.
См. Ниже пример использования счета-фактуры № 1262INV, указанного в запросе выше. Стоимость должна быть 1,04, 0,26 и 4 соответственно против 138 млн.
Любая помощь в прояснении этого вопроса будет оценена
Повторное использование псевдонима - тоже плохая идея. У вас есть ns.COSreport c
и ns.Customers c
. Я предлагаю использовать уникальные псевдонимы, представляющие ваши объекты.
Извините, эта строка была удалена по ошибке - теперь она добавлена
Спасибо - в запросе обновлены псевдонимы
У вас есть пара проблем.
В подзапросе вы используете псевдоним c
для COSReport
. Вы также используете псевдоним c
для customers
во внешнем запросе.
Более серьезная проблема заключается в том, что ваш подзапрос вообще не коррелирует с вашим внешним запросом. Вот почему он суммирует всю таблицу.
Чтобы сопоставить ваш подзапрос, вам необходимо присоединиться (в подзапросе) к одной из таблиц во внешнем запросе. Не уверен в ваших таблицах или данных, но предполагаю, что вы хотите использовать ns.tinvoice i
в предложении WHERE в своем подзапросе.
На самом деле я предпочитаю использовать CTE для удобства чтения. Вы можете взять свой подзапрос, поместить его в CTE, а затем присоединить к нему в своем основном запросе, но вы захотите добавить поля tranid
и item_id
в CTE, чтобы вы могли использовать их в своем объединении.
Обновлено: поскольку вы используете Azure SQL Server, вам не нужна точка с запятой перед WITH
.
WITH TrueCosts AS
(
SELECT
d.tranid
,d.item_id
,TrueCost = SUM(c.tranamt)
FROM ns.COSreport c
INNER JOIN ns.ProfitabilityReport d
ON c.InvoiceID = d.tranid
AND c.item_id = d.item_id
GROUP BY d.tranid
,d.item_id
)
SELECT
i.tranid
, it.item_id
, it.displayname
, tl.Item_Count * -1 Unit_Qty
, case when tl.Item_Count=0 then 0
else ((tl.GROSS_AMOUNT * -1)/ Item_Count) * -1
END as PricePerUnit
, tc.TrueCost AS 'True Cost'
, '0' AS 'Cost Per M'
FROM ns.tinvoice i
JOIN ns.transaction_lines tl on i.transaction_id = tl.transaction_id
JOIN ns.Customers c on c.customer_id = i.ENTITY_ID
JOIN ns.items it on it.item_id = tl.item_id
LEFT JOIN ns.ITEM_CLASSIFICATION it_class on it_class.list_id = it.ITEM_CLASSIFICATION_ID
LEFT JOIN TrueCosts tc ON tc.tranid = i.tranid AND tc.item_id = tl.item_id
WHERE list_item_name IS NOT NULL
AND i.tranid = '1262INV'
Спасибо! Получена следующая ошибка: Не удалось связать составной идентификатор tc.TrueCost. Вы уже подводите итоги, так что мне не нужно снова подводить итоги, не так ли?
Вы правы, суммирование происходит в CTE, поэтому вам не нужно SUM в основном запросе. Что касается полученной ошибки, вы добавили строку LEFT JOIN TrueCosts...
в свой основной запрос?
похоже, что этого не было, теперь я получаю Неправильный синтаксис рядом с ';'. (102) Итак, глядя на то, что могло быть причиной этого
Какую версию SQL Server вы используете? Единственная точка с запятой находится в самом начале запроса, а CTE требуют точки с запятой перед WITH
. Может быть, перед этим запросом в вашем скрипте была ошибка?
Сервер SQL Azure
Просто удалите точку с запятой, затем
Конечно же! Это всегда мелочи :)
Похоже, вам не хватает предложения
FROM
в основном запросе. Вероятно, вы можете взять подзапрос из спискаSELECT
и присоединить его к своей основной таблице как коррелированный подзапрос. Но нам нужно увидеть предложениеFROM
, чтобы правильно построить коррелированное соединение.