Problem with a query in Postgres that I want to move to SQL Server - sql

I have the following query in postgres that I now need to run on SQL Server. Obviously I have already changed the trunc per round and basic things, but mainly I have a problem in the principle select distinct on (c.cod_socio) tbl. * Since SQL Server does not recognize that syntax.
select distinct on (c.cod_socio)
tbl.*, h.cod_oficina, h.cod_transaccion, h.num_transaccion,
h.num_sec, h.fec_movimiento
from
sgf_det_mov_his h
inner join
sgf_cuenta c on c.cod_producto = h.cod_producto and c.cod_cuenta = h.cod_cuenta
inner join
sgf_tran t on t.cod_transaccion = h.cod_transaccion and t.cod_oficina = h.cod_oficina and t.cod_tipo_transaccion in ('DA', 'DP','NC')
inner join
(select
sgf_cuenta.cod_socio,
sum(trunc(sgf_det_mov_his.val_efectivo, 0) + trunc(sgf_det_mov_his.val_cheques, 0)) as total
from
sgf_det_mov_his, sgf_cuenta, sgf_tran
where
sgf_cuenta.cod_producto = sgf_det_mov_his.cod_producto
and sgf_cuenta.cod_cuenta = sgf_det_mov_his.cod_cuenta
and sgf_det_mov_his.sts_mov = 'A'
and sgf_tran.cod_transaccion = sgf_det_mov_his.cod_transaccion
and sgf_tran.cod_oficina = sgf_det_mov_his.cod_oficina
and sgf_cuenta.cod_producto <> 2
and sgf_tran.cod_tipo_transaccion in ('DA', 'DP','NC')
and isnull(sgf_tran.cod_uaf, 0) > 0
and isnull(sgf_tran.cod_uaf, 0) not in (71)
and sgf_cuenta.cod_cuenta not in (select cod_cuenta
from sgf_credito
where sgf_credito.cod_producto = sgf_cuenta.cod_producto
and sgf_credito.cod_cuenta = sgf_cuenta.cod_cuenta
and sts_operacion in ('A'))
and date(sgf_det_mov_his.fec_movimiento) between '2015-01-01' and '2019-01-01'
group by
sgf_cuenta.cod_socio
having
sum(trunc(sgf_det_mov_his.val_efectivo,0) + trunc(sgf_det_mov_his.val_cheques,0)) >= 5000) tbl on tbl.cod_socio = c.cod_socio
where
date(h.fec_movimiento) between '2015-01-01' and '2019-01-01'
order by
c.cod_socio, h.fec_movimiento desc

distinct on (...) simply retains the "first row" which may be emulated using row_number() over(...) and a following where clause predicate that limits to one row per partition.. Note that distinct on relies on the order by clause to decide the "first row", so you need the equivalent conditions in the over clause. Also note if you after greater query compatibility between the two databases you could use the same row_number approach in PostgreSQL.
SELECT
*
FROM (
SELECT
ROW_NUMBER() OVER (PARTITION BY c.cod_socio ORDER BY h.fec_movimiento DESC) AS rn
, c.cod_socio
, tbl.*
, h.cod_oficina
, h.cod_transaccion
, h.num_transaccion
, h.num_sec
, h.fec_movimiento
FROM sgf_det_mov_his h
INNER JOIN sgf_cuenta c ON c.cod_producto = h.cod_producto
AND c.cod_cuenta = h.cod_cuenta
INNER JOIN sgf_tran t ON t.cod_transaccion = h.cod_transaccion
AND t.cod_oficina = h.cod_oficina
AND t.cod_tipo_transaccion IN ('DA', 'DP', 'NC')
INNER JOIN (
SELECT
sgf_cuenta.cod_socio
, SUM(trunc(sgf_det_mov_his.val_efectivo, 0) + trunc(sgf_det_mov_his.val_cheques, 0)) AS total
FROM sgf_det_mov_his
, sgf_cuenta
, sgf_tran
WHERE sgf_cuenta.cod_producto = sgf_det_mov_his.cod_producto
AND sgf_cuenta.cod_cuenta = sgf_det_mov_his.cod_cuenta
AND sgf_det_mov_his.sts_mov = 'A'
AND sgf_tran.cod_transaccion = sgf_det_mov_his.cod_transaccion
AND sgf_tran.cod_oficina = sgf_det_mov_his.cod_oficina
AND sgf_cuenta.cod_producto <> 2
AND sgf_tran.cod_tipo_transaccion IN ('DA', 'DP', 'NC')
AND ISNULL(sgf_tran.cod_uaf, 0) > 0
AND ISNULL(sgf_tran.cod_uaf, 0) NOT IN (71)
AND sgf_cuenta.cod_cuenta NOT IN (
SELECT
cod_cuenta
FROM sgf_credito
WHERE sgf_credito.cod_producto = sgf_cuenta.cod_producto
AND sgf_credito.cod_cuenta = sgf_cuenta.cod_cuenta
AND sts_operacion IN ('A')
)
AND DATE(sgf_det_mov_his.fec_movimiento) BETWEEN '2015-01-01' AND '2019-01-01'
GROUP BY
sgf_cuenta.cod_socio
HAVING SUM(trunc(sgf_det_mov_his.val_efectivo, 0) + trunc(sgf_det_mov_his.val_cheques, 0)) >= 5000
) tbl ON tbl.cod_socio = c.cod_socio
WHERE DATE(h.fec_movimiento) BETWEEN '2015-01-01' AND '2019-01-01'
) AS d
WHERE d.rn = 1
ORDER BY
d.cod_socio
, d.fec_movimiento DESC

Related

Update with ROW_NUMBER() OVER

I'm getting error "Windowed functions can only appear in the SELECT or ORDER BY clauses." Can you please help me?
Iknow there are already some solutions to this problem but i don't know how to change it for my case. I am a beginner in SQL.
EDIT: I need to update column [BREAG_GUEST_SEQ] with correct sequence at UPDATE case. Every [BREAG_BGL_ID] have own sequence..
UPDATE G1
SET
G1.[BREAG_BGL_ID] = CASE WHEN G1.[BREAG_BGL_ID] <> G2.GROUP_ID THEN G2.GROUP_ID ELSE G1.[BREAG_BGL_ID] END
,G1.[BREAG_GUEST_SEQ] = CASE WHEN G1.[BREAG_BGL_ID] <> G2.GROUP_ID THEN ROW_NUMBER() OVER(ORDER BY G1.[BREAG_BRE_ID] DESC) + (SELECT ISNULL(MAX(BREAG_GUEST_SEQ), 0) FROM BOS_RESADDGUEST
WHERE DATEPART(YEAR, BREAG_DATEFROM) = DATEPART(YEAR, GETDATE()) AND BREAG_BGL_ID = G2.GROUP_ID)
ELSE G1.[BREAG_GUEST_SEQ] END
FROM
BOS_RESADDGUEST G1
INNER JOIN (
SELECT
[BRE_ID]
,MAX([BRE_DATEFROM]) AS DATEFROM
,MAX([BRE_DATETO]) AS DATETO
,MAX(BGL_ID) AS GROUP_ID
FROM
BOS_RESERVATION
LEFT JOIN BOS_UNIT_LIST ON BUL_ID = BRE_UNIT_ID
LEFT JOIN BOS_UNITTYPE_LIST ON BUL_UNITTYPE_ID = BUT_ID
LEFT JOIN BOS_GROUP_LIST ON BGL_ID = BUT_GROUP_ID
WHERE
BRE_ID = #DIALOG_BRE_ID
GROUP BY [BRE_ID]
) AS G2
ON G2.[BRE_ID] = G1.[BREAG_BRE_ID]
This isnt tested nor do you provide expected results or data structure. However, the issue is quite clear (as SMor has pointed out in the comments). This isnt the best code and the indentation is awful (i want it to be readable with scrolling left or right here on SO).
You most likely have to edit what Im joining on in the update statement at the end, because without further information from you i have to guess what the join predicate ought to be. Im sure you can figure it out from this point forward.
; WITH cte AS
(
SELECT
[BREAG_BRE_ID]
, CASE
WHEN x.[BREAG_BGL_ID] <> x.GROUP_ID THEN x.GROUP_ID
ELSE x.[BREAG_BGL_ID]
END As NewBREAGBGLID
, CASE
WHEN x.[BREAG_BGL_ID] <> x.GROUP_ID THEN ROW_NUMBER()
OVER (ORDER BY x.[BREAG_BRE_ID] DESC) +
(
SELECT ISNULL(MAX(BREAG_GUEST_SEQ), 0)
FROM BOS_RESADDGUEST
WHERE DATEPART(YEAR, BREAG_DATEFROM) = DATEPART(YEAR, GETDATE())
AND BREAG_BGL_ID = x.GROUP_ID
)
ELSE x.[BREAG_GUEST_SEQ]
END AS NewBREAGGUESTSEQ
FROM
(
SELECT g2.*, g1.[BREAG_BGL_ID], g1.[BREAG_BRE_ID], g1.[BREAG_GUEST_SEQ]
FROM
BOS_RESADDGUEST G1
INNER JOIN
(
SELECT
[BRE_ID]
,MAX([BRE_DATEFROM]) AS DATEFROM
,MAX([BRE_DATETO]) AS DATETO
,MAX(BGL_ID) AS GROUP_ID
FROM
BOS_RESERVATION
LEFT JOIN BOS_UNIT_LIST ON BUL_ID = BRE_UNIT_ID
LEFT JOIN BOS_UNITTYPE_LIST ON BUL_UNITTYPE_ID = BUT_ID
LEFT JOIN BOS_GROUP_LIST ON BGL_ID = BUT_GROUP_ID
WHERE
BRE_ID = #DIALOG_BRE_ID
GROUP BY [BRE_ID]
) AS G2
ON G2.[BRE_ID] = G1.[BREAG_BRE_ID]
) AS x
)
UPDATE
[BREAG_BGL_ID] = c.NewBREAGBGLID
, [BREAG_GUEST_SEQ] = c.NewBREAGGUESTSEQ
FROM BOS_RESADDGUEST br
INNER JOIN cte c ON br.[BREAG_BRE_ID] =c.[BREAG_BRE_ID]
You need to move the ROW_NUMBER into a derived table or CTE. You can update this directly, no need to rejoin.
You can also change the subquery to a windowed MAX
Note also that date comparisons should not use functions against the column, as this can affect performance
UPDATE G1
SET
G1.[BREAG_BGL_ID] = CASE WHEN G1.[BREAG_BGL_ID] <> G2.GROUP_ID THEN G2.GROUP_ID ELSE G1.[BREAG_BGL_ID] END
,G1.[BREAG_GUEST_SEQ] = CASE WHEN G1.[BREAG_BGL_ID] <> G2.GROUP_ID THEN G1.rn + G1.MaxSeq ELSE G1.[BREAG_GUEST_SEQ] END
FROM (
SELECT *,
ROW_NUMBER() OVER(ORDER BY G1.[BREAG_BRE_ID] DESC) AS rn,
ISNULL(MAX(CASE WHEN WHERE G1.BREAG_DATEFROM >= DATEFROMPARTS(YEAR(GETDATE()), 1, 1) THEN G1.BREAG_GUEST_SEQ END)
OVER (PARTITION BY G1.BREAG_BGL_ID), 0) AS MaxSeq
FROM
BOS_RESADDGUEST G1
) AS G1
INNER JOIN (
SELECT
[BRE_ID]
,MAX([BRE_DATEFROM]) AS DATEFROM
,MAX([BRE_DATETO]) AS DATETO
,MAX(BGL_ID) AS GROUP_ID
FROM
BOS_RESERVATION
LEFT JOIN BOS_UNIT_LIST ON BUL_ID = BRE_UNIT_ID
LEFT JOIN BOS_UNITTYPE_LIST ON BUL_UNITTYPE_ID = BUT_ID
LEFT JOIN BOS_GROUP_LIST ON BGL_ID = BUT_GROUP_ID
WHERE
BRE_ID = #DIALOG_BRE_ID
GROUP BY [BRE_ID]
) AS G2
ON G2.[BRE_ID] = G1.[BREAG_BRE_ID];

How to get biggest value from 2 or more fields in a subquery

I have a table with customers that I join with a fact table with sales, based on invoices.
What I need from my report is to get in first part the biggest value of sales based on the incoming order type (1,2,3,C,D) for a customer for last year. And in the second part to get the same but for current year. What I get as result from my current query is all incoming order types with the customer revenue made for each of them. I tried with outer apply as subquery to get only the top 1 value ordered by revenue descending, but in the result I get the same - For all order types the customer revenue. Please help! I hope my explanation isn't understood only by me (happens a lot..)
use dwh01;
WITH OrderTypeUsedLY AS
(
SELECT
c.CustomerKey
,c.BranchId
,c.CustomerId
,c.CustomerName
,ISNULL(SUM(y.[Sale_Revenue]), 0) as [Sale_Revenue_LY]
,ISNULL(SUM(y.[Sale_GrossMarginTotal]), 0) as [Sale_GrossMarginTotal_LY]
,y.IncomingOrderTypeId as IncomingOrderType_LY
FROM live.DimCustomer c
left join (SELECT s.CustomerKey,iot.IncomingOrderTypeid, s.[Sale_Revenue], s.[Sale_GrossMarginTotal] FROM [dwh01].[live].[FactSales] s
inner join live.DimDate d
on d.DateId = s.PostingDateKey
inner join live.DimIncomingOrderType iot on iot.IncomingOrderTypeKey = s.IncomingOrderTypeKey
where s.ReportCurrencyId = 'LC'
and D.Year = YEAR(GETDATE())-1 --- Last Year
) y on c.CustomerKey = y.CustomerKey
where c.CustomerKey = '157053'
group by c.CustomerKey, c.CustomerId, c.CustomerName, c.BranchId, y.IncomingOrderTypeId
),
--*********************************************************************************************************************************--
OrderTypeCY as(
SELECT
c.CustomerKey
,c.BranchId
,c.SalesRepKey
,c.CustomerId
,c.CustomerName
,ISNULL(SUM(y.[Sale_Revenue]), 0) as [Sale_Revenue_CY]
,ISNULL(SUM(y.[Sale_GrossMarginTotal]), 0) as [Sale_GrossMarginTotal_CY]
,y.IncomingOrderTypeId as IncomingOrderType_CY
FROM live.DimCustomer c
left join (SELECT s.CustomerKey,iot.IncomingOrderTypeid, s.[Sale_Revenue], s.[Sale_GrossMarginTotal] FROM [dwh01].[live].[FactSales] s
inner join live.DimDate d
on d.DateId = s.PostingDateKey
inner join live.DimIncomingOrderType iot on iot.IncomingOrderTypeKey = s.IncomingOrderTypeKey
where s.ReportCurrencyId = 'LC'
and D.Year = YEAR(GETDATE()) --- Current Year
) y on c.CustomerKey = y.CustomerKey
where c.CustomerKey = '157053'
group by c.CustomerKey, c.CustomerId, c.CustomerName, c.BranchId, y.IncomingOrderTypeId, c.SalesRepKey
)
--*********************************************************************************************************************************--
SELECT
otly.BranchId,
rep.SalesRepId,
rep.SalesRepName,
otly.CustomerId,
otly.CustomerName,
otly.Sale_Revenue_LY,
otly.Sale_GrossMarginTotal_LY,
IncomingOrderType_LY,
otcy.Sale_Revenue_CY,
otcy.Sale_GrossMarginTotal_CY,
IncomingOrderType_CY
from OrderTypeUsedLY otly
left join OrderTypeCY otcy
on otly.CustomerKey = otcy.CustomerKey
join live.DimCustomer cus on cus.CustomerKey = otcy.CustomerKey
join live.DimSalesRep rep on rep.SalesRepKey = otcy.SalesRepKey
order by otcy.Sale_Revenue_CY desc, otly.Sale_Revenue_LY desc
,rep.SalesRepId
And here is the outer apply I tried:
outer apply (
SELECT top 1
iot.IncomingOrderTypeId,
Sale_Revenue
FROM [dwh01].[live].DimIncomingOrderType iot
where iot.IncomingOrderTypeKey = y.IncomingOrderTypeKey
order by Sale_Revenue desc) x
In the first select ( with OrderTypeUsed_LY ) I get this:
And I get the same in the second select, but with the values for current year.
The purpose of the report is to see the difference in the incoming order type most used (most profit made with it) for a customer last year and to see if he continues to use it this year, or uses another incoming order type this year.
Again I'm sorry for the bad explanation, I'm trying my best (I understand myself very well)
Here is the expected result:
Expected Result
I marked in red the last year part and in green the current year part.
If you change the subquery to:
SELECT
iot.IncomingOrderTypeKey,
MAX(Sale_Revenue)
FROM [dwh01].[live].DimIncomingOrderType iot
GROUP BY iot.IncomingOrderTypeKey
then you can JOIN (not APPLY) directly on IncomingOrderTypeKey AND Sale_Revenue.
Try this:
USE dwh01;
DECLARE #CustomerKey varchar(6) = '157053'
, #ReportCurrencyId varchar(2) = 'LC'
, #CurrentYear int = YEAR(GETDATE())
, #TargetYear int = YEAR(GETDATE())-1
;
WITH FactsTable AS
(
SELECT
s.CustomerKey
, i.IncomingOrderTypeid
, [Sale_Revenue] = ISNULL(s.[Sale_Revenue] , 0)
, [Sale_GrossMarginTotal] = ISNULL(s.[Sale_GrossMarginTotal], 0)
, d.[Year]
FROM [dwh01].[live].[FactSales] s
inner join live.DimDate d on d.DateId = s.PostingDateKey
inner join live.DimIncomingOrderType i on i.IncomingOrderTypeKey = s.IncomingOrderTypeKey
where
s.CustomerKey = #CustomerKey
and s.ReportCurrencyId = #ReportCurrencyId
)
, OrderTypeTable
(
SELECT
c.CustomerKey
, c.BranchId
, c.CustomerId
, c.CustomerName
, c.SalesRepKey
, IncomingOrderType_LY = SUM(CASE WHEN y.[Year] = #TargetYear THEN y.IncomingOrderTypeId ELSE 0 END)
, [Sale_Revenue_LY] = SUM(CASE WHEN y.[Year] = #TargetYear THEN y.[Sale_Revenue] ELSE 0 END)
, [Sale_GrossMarginTotal_LY] = SUM(CASE WHEN y.[Year] = #TargetYear THEN y.[Sale_GrossMarginTotal] ELSE 0 END)
, IncomingOrderType_LY = SUM(CASE WHEN y.[Year] = #CurrentYear THEN y.IncomingOrderTypeId ELSE 0 END)
, [Sale_Revenue_CY] = SUM(CASE WHEN y.[Year] = #CurrentYear THEN y.[Sale_Revenue] ELSE 0 END)
, [Sale_GrossMarginTotal_CY] = SUM(CASE WHEN y.[Year] = #CurrentYear THEN y.[Sale_GrossMarginTotal] ELSE 0 END)
FROM live.DimCustomer c
left join FactsTable y on y.CustomerKey = c.CustomerKey
group by
c.CustomerKey
, c.BranchId
, c.CustomerId
, c.CustomerName
, y.IncomingOrderTypeId
, c.SalesRepKey
)
SELECT
O.BranchId
, R.SalesRepId
, R.SalesRepName
, O.CustomerId
, O.CustomerName
, O.Sale_Revenue_LY
, O.Sale_GrossMarginTotal_LY
, O.IncomingOrderType_LY
, O.Sale_Revenue_CY
, O..Sale_GrossMarginTotal_CY
, O.IncomingOrderType_CY
from OrderTypeTable O
join live.DimSalesRep R on R.SalesRepKey = O.SalesRepKey
order by
O.Sale_Revenue_CY desc
, O.Sale_Revenue_LY desc
, R.SalesRepId
The solution is with using row_number() function in the inner query of the first CTE:
(
select *, row_number() over (partition by x0.CustomerKey order by x0.Sale_Revenue desc) as rn
from
(
select fs.CustomerKey, iot.IncomingOrderTypeKey,
sum(fs.Sale_Revenue) as Sale_Revenue
FROM [dwh01].[live].DimIncomingOrderType iot
join live.FactSales fs
on iot.IncomingOrderTypeKey = fs.IncomingOrderTypeKey
join live.DimDate d
on d.DateId = fs.PostingDateKey
where d.[year] = #CurrentYear
GROUP BY fs.CustomerKey, iot.IncomingOrderTypeKey
) as x0
) as x1 on x1.CustomerKey = s.CustomerKey
The row_number() function gets only the first row from the result for each customer, and that is with the biggest sale revenue ( order by sale_revenue desc).

How can I order by sum of three column from different tables?

select username,
(select COUNT(OpenUser) from TIcket t with(nolock) where t.OpenUser = u.UserName and cast(t.CompletedDate as date) = cast(getdate() as date) and t.IssueClass = 58) as ServiceNote,
(select COUNT(AssignUser) from TIcket t with(nolock) where ((t.AssignUser = u.UserName and t.Status = 1) and t.IssueClass != 58)) as status1,
(select COUNT(PickUpUser) from TIcket t with(nolock) where ((t.PickUpUser = u.UserName and t.Status = 2) and t.IssueClass != 58)) as status2
from users u
where isinactive = 0
and UserLevel > -1 and First_Name != ''
and center_id = '100'
I made query for my program. And I want to order by sum of three field ServiceNote,status1,status2.
I tried to order using 'Sum',(like order by (ServiceNote,status1,status2) but it doesn't work.
Doesn't this work?
order by (serviceNote + status1 + status2)
This works in most databases, but not in SQL Server. For that, use a CTE or subquery:
with cte as (
<your query here>
)
select cte.*
from cte
order by (serviceNote + status1 + status2);

Error With total Column which calculate the summation of Row values

I created a pivot query which calculate the sum of specific transaction and i want to add additional column which calculate the sum of all transaction for every ID, But my total column give me nulls only for all IDs, Any one can help with that?
this is my Query:
SELECT
AccountID
, OpeningBalance
, OpeningBalanceStatus
, ISNULL([CI], 0) AS CI
, ISNULL([CO], 0) AS CO
, ISNULL([SI], 0) AS SI
, ISNULL([CN], 0) AS CN
, ISNULL([PI], 0) AS PI
, ISNULL([JE], 0) AS JE
, ISNULL([NR], 0) AS NR
, [OpeningBalance]+[CI]+[CO]+[SI]+[CN]+[PI]+[JE]+[NR] AS TOTAL
FROM (SELECT
Accounting.AccDocumentDetails.AccountID
, Accounting.AccDocumentDetails.AmountStatus
, Accounting.AccAccounts.AccountType
, Accounting.AccDocumentHeader.CodeTypePart
, AccAccounts_1.OpeningBalance
, AccAccounts_1.OpeningBalanceStatus
, CASE
WHEN AmountStatus = 'd'
THEN (Amount * 1)
WHEN AmountStatus = 'C'
THEN (Amount * - 1)
END AS NewAmount FROM Accounting.AccDocumentDetails
INNER JOIN Accounting.AccAccounts
ON Accounting.AccDocumentDetails.AccountID = Accounting.AccAccounts.ID
INNER JOIN Accounting.AccChartOfAccounts
ON Accounting.AccChartOfAccounts.ID = Accounting.AccAccounts.ParentNode
INNER JOIN Accounting.AccDocumentHeader
ON Accounting.AccDocumentDetails.AccDocumentHeaderID = Accounting.AccDocumentHeader.ID
INNER JOIN Accounting.AccAccounts AS AccAccounts_1
ON Accounting.AccDocumentDetails.AccountID = AccAccounts_1.ID) AS PivotSelect PIVOT( SUM(NewAmount) FOR CodeTypePart IN ([ci],[CO],[SI],[CN],[PI],[JE],[NR]) ) AS PVT
and this is my output
enter image description here
One way to have the total column is you can use your query as sub query, then create the computation for the total on the outer query. Or you can use cte as well
WITH t_pvt AS (
SELECT AccountID
,OpeningBalance
,OpeningBalanceStatus
,ISNULL([CI], 0) AS CI
,ISNULL([CO], 0) AS CO
,ISNULL([SI], 0) AS SI
,ISNULL([CN], 0) AS CN
,ISNULL([PI], 0) AS PI
,ISNULL([JE], 0) AS JE
,ISNULL([NR], 0) AS NR
FROM (SELECT Accounting.AccDocumentDetails.AccountID
,Accounting.AccDocumentDetails.AmountStatus
,Accounting.AccAccounts.AccountType
,Accounting.AccDocumentHeader.CodeTypePart
,AccAccounts_1.OpeningBalance
,AccAccounts_1.OpeningBalanceStatus
,CASE WHEN AmountStatus = 'd'
THEN (Amount * 1)
WHEN AmountStatus = 'C'
THEN (Amount * - 1)
END AS NewAmount
FROM Accounting.AccDocumentDetails
INNER JOIN Accounting.AccAccounts
ON Accounting.AccDocumentDetails.AccountID = Accounting.AccAccounts.ID
INNER JOIN Accounting.AccChartOfAccounts
ON Accounting.AccChartOfAccounts.ID = Accounting.AccAccounts.ParentNode
INNER JOIN Accounting.AccDocumentHeader
ON Accounting.AccDocumentDetails.AccDocumentHeaderID = Accounting.AccDocumentHeader.ID
INNER JOIN Accounting.AccAccounts AS AccAccounts_1
ON Accounting.AccDocumentDetails.AccountID = AccAccounts_1.ID) AS PivotSelect
PIVOT (SUM(NewAmount)
FOR CodeTypePart IN ([ci],[CO],[SI],[CN],[PI],[JE],[NR])) AS PVT
)
SELECT *
,[OpeningBalance]+[CI]+[CO]+[SI]+[CN]+[PI]+[JE]+[NR] AS TOTAL
FROM t_pvt
With CTE
AS
( select column1 as c1 from tbl)
Select c1 from CTE
thats a simple example of CTE syntax and how you can use it

Select inside CASE THEN

I need to select the project rate or shift rate that has the effective date less than today.
SELECT
CASE
WHEN ISNULL(s.rate,0) = 0
THEN SELECT TOP 1 pr.rate FROM ProjectRates pr WHERE (pr.projectID = p.ID) AND (pr.effectiveDate < GETDATE()) ORDER BY pr.effectiveDate DESC
--p.rate
ELSE SELECT TOP 1 sr.rate FROM ShiftRates sr WHERE (sr.shiftID = s.ID) AND (sr.effectiveDate < GETDATE()) ORDER BY pr.effectiveDate DESC
--s.rate
END AS rate
FROM Projects p
INNER JOIN Shifts s ON (p.ID = s.projectID)
WHERE (p.ID = #projectID)
Please note that this code snippet is part of a larger stored proc and thus it must be within a CASE statement.
Subqueries need parentheses:
SELECT (CASE WHEN ISNULL(s.rate, 0) = 0
THEN (SELECT TOP 1 pr.rate
FROM ProjectRates pr
WHERE (pr.projectID = p.ID) AND (pr.effectiveDate < GETDATE())
ORDER BY pr.effectiveDate DESC
)
ELSE (SELECT TOP 1 sr.rate
FROM ShiftRates sr
WHERE (sr.shiftID = s.ID) AND (sr.effectiveDate < GETDATE())
ORDER BY pr.effectiveDate DESC
) --s.rate
END) AS rate
FROM Projects p INNER JOIN
Shifts s
ON p.ID = s.projectID
WHERE p.ID = #projectID;