Aliasing in SQL Server - sql-server

I wrote this query in Oracle and want to compile it as well on SQL Server:
SELECT DISTINCT
HOLDER_CODE, CALCULATED_AMOUNT
FROM
(SELECT
DA.HOLDER_CODE,
ROUND(FAB.AMOUNT * FCE.EXCHANGE_RATE,0) AS CALCULATED_AMOUNT,
FAB.BALANCE_DATE_ID as FAB_DATE,
MAX(FAB.BALANCE_DATE_ID) OVER (PARTITION BY DA.HOLDER_CODE) as MAX_DATE_BALANCE
FROM
DIM_ACCOUNT DA
JOIN
FACT_AS_BALANCE FAB ON FAB.ACCOUNT_ID = DA.ID
JOIN
DIM_AS_CHARACTERISTICS DAC ON DAC.ID = FAB.BALANCE_TYPE_ID
LEFT JOIN
FACT_CURRENCY_EXCHANGE FCE ON FCE.FROM_CURRENCY_ID = FAB.CURRENCY_ID
WHERE
DAC.BALANCE_CLOSING_FLAG = 'Y'
AND TO_CURRENCY_ID = (SELECT DC.ID
FROM DIM_CURRENCY DC
WHERE DC.IS_DEFAULT_CURRENCY = 'Y')
AND FAB.AMOUNT > 0)
WHERE
FAB_DATE = MAX_DATE_BALANCE
ORDER BY
CALCULATED_AMOUNT DESC;
But when I run it I get the following exception:
Error: Incorrect syntax near the keyword 'WHERE'. SQLState: S0001
ErrorCode: 156
So I guess, it's the last where clause, which indicates this. What is wrong and what should it be?

You just need to alias the subquery
SELECT DISTINCT HOLDER_CODE, CALCULATED_AMOUNT
FROM (
SELECT DA.HOLDER_CODE,
//// snip subquery
AND FAB.AMOUNT > 0
) alias_name_here //<--- here
WHERE FAB_DATE = MAX_DATE_BALANCE
ORDER BY CALCULATED_AMOUNT DESC;
You can use as alias_name_here or just alias_name_here - SQL Server allows either syntax.

you must give a name at your "table"
i give is with "as T"
SELECT DISTINCT HOLDER_CODE, CALCULATED_AMOUNT
FROM (
SELECT DA.HOLDER_CODE,
ROUND(FAB.AMOUNT * FCE.EXCHANGE_RATE,0) AS CALCULATED_AMOUNT,
FAB.BALANCE_DATE_ID as FAB_DATE,
MAX(FAB.BALANCE_DATE_ID) OVER (PARTITION BY DA.HOLDER_CODE) as MAX_DATE_BALANCE
FROM DIM_ACCOUNT DA
JOIN FACT_AS_BALANCE FAB ON FAB.ACCOUNT_ID = DA.ID
JOIN DIM_AS_CHARACTERISTICS DAC ON DAC.ID = FAB.BALANCE_TYPE_ID
LEFT JOIN FACT_CURRENCY_EXCHANGE FCE ON FCE.FROM_CURRENCY_ID = FAB.CURRENCY_ID
WHERE DAC.BALANCE_CLOSING_FLAG = 'Y'
AND TO_CURRENCY_ID = (
SELECT DC.ID FROM DIM_CURRENCY DC
WHERE DC.IS_DEFAULT_CURRENCY = 'Y')
AND FAB.AMOUNT > 0
) as T
WHERE FAB_DATE = MAX_DATE_BALANCE
ORDER BY CALCULATED_AMOUNT DESC;

Related

Converting Oracle Query into T-SQL query using WITH

I have a query from an old database that we converting into T-SQL, but having issues using CTE:
Original Query in Oracle:
select company_name, display_name, active_flag, naic_code, group_number, alien_code, fein,
status_desc, status_detail_desc, due_to_merger_flag, co_code, to_char(status_date, 'MM/DD/YYYY')
Inactive_Date, active_flag from
(select nm.COMPANY_NAME, cmp.recordid_number, orgtp.display_name, cmp.active_flag,
cmp.naic_code, grpnm.group_number, cmp.alien_code, cmp.fein, st.status_desc, stdt.status_detail_desc,
storgjn.due_to_merger_flag, storgjn.co_code, storgjn.status_date, st.active_flag as activestatus,
max(storgjn.status_date) over (partition by cmp.recordid_number, orgtp.display_name) max_status_date
from aip.co_company cmp join aip.CO_NAME nm on cmp.COMPANY_ID = nm.company_id and nm.active_flag = 1
left outer join aip.co_company_group_jn cmpgrpjn on nm.COMPANY_ID = cmpgrpjn.company_id and cmpgrpjn.active_flag = 1
left outer join aip.co_group_name grpnm on cmpgrpjn.group_id = grpnm.group_id and grpnm.active_flag = 1
join aip.co_org org on cmp.COMPANY_ID = org.company_id
join aip.co_org_type orgtp on org.org_type_id = orgtp.org_type_id
join aip.co_status_org_jn storgjn on org.org_id = storgjn.org_id
join aip.co_status_detail stdt on storgjn.status_detail_id = stdt.status_detail_id
join aip.co_status st on stdt.status_id = st.status_id
WHERE cmp.recordid_number = '10632' AND
stdt.status_detail_desc <> 'Record Begin Date')
WHERE status_date = max_status_date
And converting into T-SQl im using:
WITH YOURCTE(WHATEVA) AS
(
SELECT nm.COMPANY_NAME, cmp.recordid_number, orgtp.display_name, cmp.active_flag,
cmp.naic_code, grpnm.group_number, cmp.alien_code, cmp.fein, st.status_desc, stdt.status_detail_desc,
storgjn.due_to_merger_flag, storgjn.co_code, storgjn.status_date, st.active_flag as activestatus,
max(storgjn.status_date) over (partition by cmp.recordid_number, orgtp.display_name) max_status_date
from aip.co_company cmp join aip.CO_NAME nm on cmp.COMPANY_ID = nm.company_id and nm.active_flag = 1
left outer join aip.co_company_group_jn cmpgrpjn on nm.COMPANY_ID = cmpgrpjn.company_id and cmpgrpjn.active_flag = 1
left outer join aip.co_group_name grpnm on cmpgrpjn.group_id = grpnm.group_id and grpnm.active_flag = 1
join aip.co_org org on cmp.COMPANY_ID = org.company_id
join aip.co_org_type orgtp on org.org_type_id = orgtp.org_type_id
join aip.co_status_org_jn storgjn on org.org_id = storgjn.org_id
join aip.co_status_detail stdt on storgjn.status_detail_id = stdt.status_detail_id
join aip.co_status st on stdt.status_id = st.status_id
WHERE cmp.recordid_number = '10632' AND
stdt.status_detail_desc <> 'Record Begin Date'
)
select company_name, display_name, active_flag, naic_code, group_number, alien_code, fein,
status_desc, status_detail_desc, due_to_merger_flag, co_code, CONVERT(VARCHAR(10),status_date,120) AS Inactive_Date,
active_flag
FROM YOURCTE
WHERE status_date = max_status_date
But I get the following error :
Msg 8158, Level 16, State 1, Line 2
'YOURCTE' has more columns than were specified in the column list.
The reason i have more columns in my cte is because I'm using the recordid_number column to bring other data for where conditioning. I will appreciate some help, thank you.
Either replace "WHATEVA" with a complete list of the column aliases you want to use, or remove it and let the original column names stand.
Inherit
;WITH YOURCTE AS
(...
Explicit
;WITH YOURCTE (COMPANY_NAME, recordid_number, ...) AS
(...

Combining multiple SQL's into a single SQL

Hi have the following queries
(SELECT COUNT(DISTINCT KUNDNR) CHECKED_CUSTOMER from CLNT0001.TCM_CHECK_SUMMARY
where '20170322000000000' <= HISTVON and HISTVON < '20170323000000000' and INSTITUTSNR='0001')
and
SELECT clientNumber
,creationDate
,customerNumber
,checkedCustomer
,CLNT0001.TCM_CHECK_SUMMARY.COUNTRY_CODE countryCode
,CLNT0001.TCM_CHECK_SUMMARY.PST_KURZTEXT personStatus
,CLNT0001.TCM_CASE_COUNTRY_GROUP.COUNTRY_CODE homeCountryCode
,CLNT0001.TCM_CASE_COUNTRY_GROUP.PST_LFD_NR personStatusId
,CLNT0001.TCM_CASE_COUNTRY_GROUP.REGULATION regulation
,caseStatus
,COC_SCORE_COUNT cocCaseCount
FROM (
SELECT GEPRUEFT_JN checkedCustomer
,INSTITUTSNR clientNumber
,KUNDNR customerNumber
,CASE_STATUS caseStatus
,MAX(CREATION_DATE) creationDate
FROM CLNT0001.TAXACTCASE
WHERE GEPRUEFT_JN = 'J' AND CREATION_DATE>='20170322000000000' AND
CREATION_DATE<='20170323000000000'
GROUP BY KUNDNR
,INSTITUTSNR
,GEPRUEFT_JN
,CASE_STATUS
) T1
INNER JOIN CLNT0001.TCM_CHECK_SUMMARY ON T1.customerNumber = CLNT0001.TCM_CHECK_SUMMARY.KUNDNR
INNER JOIN CLNT0001.TCM_CASE_COUNTRY_GROUP ON T1.customerNumber = CLNT0001.TCM_CASE_COUNTRY_GROUP.KUNDNR
WHERE T1.creationDate <= CLNT0001.TCM_CHECK_SUMMARY.HISTBIS
AND T1.creationDate >= CLNT0001.TCM_CHECK_SUMMARY.HISTVON
I need the CHECKED_CUSTOMER column as a part of the second query's result set, i am not able to figure out a way to do this, is this possible ?
SELECT clientNumber,creationDate,customerNumber,checkedCustomer
,CLNT0001.TCM_CHECK_SUMMARY.COUNTRY_CODE countryCode
,CLNT0001.TCM_CHECK_SUMMARY.PST_KURZTEXT personStatus
,CLNT0001.TCM_CASE_COUNTRY_GROUP.COUNTRY_CODE homeCountryCode
,CLNT0001.TCM_CASE_COUNTRY_GROUP.PST_LFD_NR personStatusId
,CLNT0001.TCM_CASE_COUNTRY_GROUP.REGULATION regulation
,caseStatus,COC_SCORE_COUNT cocCaseCount ,CHECKED_CUSTOMER
FROM (
SELECT GEPRUEFT_JN checkedCustomer,INSTITUTSNR clientNumber ,KUNDNR customerNumber ,CASE_STATUS caseStatus,MAX(CREATION_DATE) creationDate,COUNT(DISTINCT b.KUNDNR) CHECKED_CUSTOMER
FROM CLNT0001.TAXACTCASE
LEFT JOIN CLNT0001.TCM_CHECK_SUMMARY b ON CLNT0001.TAXACTCASE.KUNDNR=b.KUNDNR
WHERE GEPRUEFT_JN = 'J' AND CREATION_DATE>='20170322000000000' AND
CREATION_DATE<='20170323000000000'
GROUP BY KUNDNR,INSTITUTSNR ,GEPRUEFT_JN,CASE_STATUS
) T1 INNER JOIN CLNT0001.TCM_CHECK_SUMMARY ON T1.customerNumber = CLNT0001.TCM_CHECK_SUMMARY.KUNDNR
INNER JOIN CLNT0001.TCM_CASE_COUNTRY_GROUP ON T1.customerNumber = CLNT0001.TCM_CASE_COUNTRY_GROUP.KUNDNR
WHERE T1.creationDate <= CLNT0001.TCM_CHECK_SUMMARY.HISTBIS
AND T1.creationDate >= CLNT0001.TCM_CHECK_SUMMARY.HISTVON

How to avoid to duplicate a subquery in a query

I'm running a query that contains the same subquery two times, one used in a inner join condition and the another in a outer join. I'm highlighting the repeated subquery with **. How can I optimize this in order to run only once?
SELECT DISTINCT dbo.tb_contato.Nome, dbo.tb_contato.id_contato, dbo.tb_contato.Sexo, dbo.tb_contato.codigo, dbo.tb_email.email
FROM dbo.tb_contato INNER JOIN
dbo.tb_email ON dbo.tb_contato.id_contato = dbo.tb_email.id_contato INNER JOIN
dbo.tb_empresa ON dbo.tb_empresa.id_empresa = dbo.tb_contato.id_empresa LEFT OUTER JOIN
(SELECT dbo.tb_interacao.IDContato AS id_contato
FROM dbo.tb_interacao INNER JOIN
**(SELECT MAX(IDInteracao) AS IDIntMax, IDPerfilParticipante AS id_perfil_participante, IDProjeto, IDContato
FROM dbo.tb_interacao AS tb_interacao_2
GROUP BY IDPerfilParticipante, IDProjeto, IDContato)** AS IntMax1 ON dbo.tb_interacao.IDInteracao = IntMax1.IDIntMax INNER JOIN
dbo.tb_projeto ON dbo.tb_interacao.IDProjeto = dbo.tb_projeto.id_projeto INNER JOIN
dbo.tb_status_processo ON dbo.tb_interacao.IDStatusProcesso = dbo.tb_status_processo.id_status_processo
WHERE (dbo.tb_projeto.id_projeto = 2057) AND (dbo.tb_interacao.IDPerfilParticipante = 1) AND (dbo.tb_status_processo.id_status_processo = 7) OR
(dbo.tb_projeto.id_projeto = 2057) AND (dbo.tb_interacao.IDPerfilParticipante = 1) AND (dbo.tb_status_processo.id_status_processo = 6) OR
(dbo.tb_interacao.IDPerfilParticipante = 1) AND (dbo.tb_status_processo.id_status_processo = 6) AND (dbo.tb_projeto.id_grupo = 55) OR
(dbo.tb_interacao.IDPerfilParticipante = 1) AND (dbo.tb_status_processo.id_status_processo = 7) AND (dbo.tb_projeto.id_grupo = 55))
AS ConvidadosOut ON dbo.tb_contato.id_contato = ConvidadosOut.id_contato INNER JOIN
(SELECT tb_interacao_1.IDContato AS id_contato
FROM dbo.tb_interacao AS tb_interacao_1 INNER JOIN
**(SELECT MAX(IDInteracao) AS IDIntMax, IDPerfilParticipante AS id_perfil_participante, IDProjeto, IDContato
FROM dbo.tb_interacao AS tb_interacao_3
GROUP BY IDPerfilParticipante, IDProjeto, IDContato)** AS IntMax2 ON tb_interacao_1.IDInteracao = IntMax2.IDIntMax INNER JOIN
dbo.tb_projeto AS tb_projeto_1 ON tb_interacao_1.IDProjeto = tb_projeto_1.id_projeto INNER JOIN
dbo.tb_status_processo AS tb_status_processo_1 ON tb_interacao_1.IDStatusProcesso = tb_status_processo_1.id_status_processo
WHERE (tb_projeto_1.id_projeto = 181) AND (IntMax2.id_perfil_participante = 1) AND (tb_status_processo_1.id_status_processo = 4) OR
(tb_projeto_1.id_projeto = 1581) AND (IntMax2.id_perfil_participante = 1) AND (tb_status_processo_1.id_status_processo = 5) OR
(IntMax2.id_perfil_participante = 1) AND (tb_status_processo_1.id_status_processo = 6) AND (tb_projeto_1.id_grupo = 62)) AS ConvidadosIn ON
dbo.tb_contato.id_contato = ConvidadosIn.id_contato
WHERE (dbo.tb_email.email_visibility = 0 OR
dbo.tb_email.email_visibility IS NULL) AND (dbo.tb_empresa.id_pais = 1) AND (dbo.tb_contato.Fonte <> 'salesloft_orange' AND
dbo.tb_contato.Fonte <> 'salesloft_int_orange' OR
dbo.tb_contato.Fonte IS NULL) AND (dbo.tb_contato.id_contato_visibility = 1 OR
dbo.tb_contato.id_contato_visibility IS NULL) AND (ConvidadosOut.id_contato IS NULL)
I hope you are using SQL server 2005 or later. You can safely try using Common table expressions for the purpose as stated in your question.
Below is an example of script from adventureworks database:
USE AdventureWorks2008R2;
GO
-- Define the CTE expression name and column list.
WITH Sales_CTE (SalesPersonID, SalesOrderID, SalesYear)
AS
-- Define the CTE query.
(
SELECT SalesPersonID, SalesOrderID, YEAR(OrderDate) AS SalesYear
FROM Sales.SalesOrderHeader
WHERE SalesPersonID IS NOT NULL
)
-- Define the outer query referencing the CTE name.
SELECT SalesPersonID, COUNT(SalesOrderID) AS TotalSales, SalesYear
FROM Sales_CTE
GROUP BY SalesYear, SalesPersonID
ORDER BY SalesPersonID, SalesYear;
GO

No column name was specified for column 2 of 'a' error

I have a MySQL query and I ran it working fine but same query showing error in SQL Server.
SQL Server query:
SELECT
COUNT(*) cnt
FROM
(SELECT DISTINCT
tc_id, MAX(exn_time), STATUS
FROM
release_details a, tc_details b
WHERE
a.project = b.project
AND a.tc_id = b.tc_name
AND logicaldel = 0
AND a.project = 'test'
GROUP BY
tc_id, STATUS) a
WHERE
a.status = 'PASS';
Error:
No column name was specified for column 2 of 'a'.
How do I modify the above query?
Use the Alias name for your inner query.You are getting the MAX(exn_time) but not specified the name for that column that's why throwing the error. And you can use the Joins to the tables to make it more readable.
SELECT COUNT(*) cnt
FROM (
SELECT DISTINCT
tc_id,
MAX(exn_time) AS Maxtime ,
STATUS
FROM
release_details a JOIN tc_details b
ON a.project= b.project
AND a.tc_id = b.tc_name
WHERE
logicaldel = 0
AND a.project ='test'
GROUP BY
tc_id,
STATUS
) a
WHERE a.status='PASS';
You missed to give Alias name inside subquery
Also as mentioned by Marc_s you need to use proper Inner Join, keep the join condition ON clause and move the filter to where clause
SELECT Count(*) cnt
FROM (SELECT DISTINCT tc_id,
Max(exn_time) Max_exn_time,
STATUS
FROM release_details a
INNER JOIN tc_details b
ON a.project = b.project
AND a.tc_id = b.tc_name
WHERE a.project = 'test'
AND logicaldel = 0
GROUP BY tc_id,
STATUS) a
WHERE a.status = 'PASS';
Your issue is obviously that your second column in the resultset a doesn't have an alias.
You can rewrite the whole query to this for the same result:
SELECT
COUNT(DISTINCT tc_id) cnt
FROM
release_details a
JOIN
tc_details b
ON
a.project = b.project
AND a.tc_id = b.tc_name
WHERE
logicaldel = 0
AND a.project = 'test'
AND STATUS = 'PASS'
Since STATUS only can have the value 'PASS', MAX(exn_time) is not helping your counting, DISTINCT should not be used in the beginning of a SELECT when using group by like in your case, it is redundant

Sub query in Store Procedure

I have a query in sql stored procedure. I want to get record from other query from its id how I do that.
SELECT t.Name ,t.CreatedDate ,t.CreatedBy , t.Amount
,t.Margin ,t.Probability ,t.Id
FROM (SELECT a = 1) a
CROSS JOIN
(SELECT
Name = HirschInternational_MSCRM.dbo.SalesOrderBase.Name
,CreatedDate=HirschInternational_MSCRM.dbo.SalesOrderBase.CreatedOn
,CreatedBy=HirschInternational_MSCRM.dbo.SystemUserBase.FullName
,Amount = totalamount
,Probability=CloseProbability
,Id=SalesOrderId
,Margin=(SELECT ( ISNULL( ((Sum(Price)-Sum(CurrentCost)) / NULLIF( Sum(Price), 0 ))*100, 0 ) )
FROM HirschInternational_MSCRM.dbo.ProductBase
JOIN HirschInternational_MSCRM.dbo.SalesOrderDetailBase
ON HirschInternational_MSCRM.dbo.SalesOrderDetailBase.ProductId = HirschInternational_MSCRM.dbo.ProductBase.ProductId
JOIN HirschInternational_MSCRM.dbo.SalesOrderBase
ON HirschInternational_MSCRM.dbo.SalesOrderBase.SalesOrderId = HirschInternational_MSCRM.dbo.SalesOrderDetailBase.SalesOrderId)
FROM HirschInternational_MSCRM.dbo.SalesOrderBase
JOIN HirschInternational_MSCRM.dbo.OpportunityBase
ON HirschInternational_MSCRM.dbo.SalesOrderBase.Opportunityid = HirschInternational_MSCRM.dbo.OpportunityBase.Opportunityid
JOIN HirschInternational_MSCRM.dbo.SystemUserBase
ON HirschInternational_MSCRM.dbo.SystemUserBase.SystemUserId = HirschInternational_MSCRM.dbo.SalesOrderBase.CreatedBy
WHERE YEAR(HirschInternational_MSCRM.dbo.SalesOrderBase.CreatedOn)=YEAR(GETDATE())
I want Margin from every record I want Output like
It's not entirely clear what you want, but you might be looking for something like
select *
from (your SQL SELECT statement goes here) t1
where id = ?;
I want to get margin of every record how I filter margin query for SalesOrderId
like
Margin=(SELECT ( ISNULL( ((Sum(Price)-Sum(CurrentCost)) / NULLIF( Sum(Price), 0 ))*100, 0 ) )
FROM HirschInternational_MSCRM.dbo.ProductBase
JOIN HirschInternational_MSCRM.dbo.SalesOrderDetailBase
ON HirschInternational_MSCRM.dbo.SalesOrderDetailBase.ProductId = HirschInternational_MSCRM.dbo.ProductBase.ProductId
JOIN HirschInternational_MSCRM.dbo.SalesOrderBase
ON HirschInternational_MSCRM.dbo.SalesOrderBase.SalesOrderId = HirschInternational_MSCRM.dbo.SalesOrderDetailBase.SalesOrderId
Where HirschInternational_MSCRM.dbo.SalesOrderBase.SalesOrderId= //SalesOrderId that I get in main query)
how I pass that SalesOrderId in this query

Resources