mssql syntax error near the keyword 'in' - sql

When i execute below query in sql server i got below error
Incorrect syntax near the keyword 'in'
Query:
select projectid
from projects
where iif(1!=1,
projects.projectid in (1,16,17,18,19,20,21,22,23),
1);

This will work.
Explanation: you cannot use IN operator in THEN part of CASE Statement, that's why use nested CASE statements. Now, this query will give you no record because "1 != 1" always returns false and THEN part will not execute.
SELECT projectid
FROM projects
WHERE
projectid = CASE
WHEN 1 != 1
THEN
CASE
WHEN projectid IN (1,16,17,18,19,20,21,22,23)
THEN projectid
ELSE 1 END
END;
Now, there is no syntax error near IN keyword. You can modify this query according to your requirement.

The equivalent logic is:
select p.projectid
from projects p
where (1 = 1) or p.projectid in (1, 16, 17, 18, 19, 20, 21, 22, 23);
However, this is overkill, because the first expression involves only constants and is always true. More commonly, you would have something like:
where (#TakeAllFlag = 1) or p.projectid in (1, 16, 17, 18, 19, 20, 21, 22, 23);
Also, if you are learning SQL -- and not using MS Access -- learn the CASE statement, not IIF(). CASE is standard SQL and available in basically all databases.

This should be as simple as:
select projectid
from projects
where projects.projectid in (1,16,17,18,19,20,21,22,23)
Don't see any sense of putting an IIF function in the where clause.
iif(1!=1, projects.projectid in (1,16,17,18,19,20,21,22,23), 1)
In simple English the above line interoperates as if 1 is not equal to 1 then use the IN expression else return 1
1 is always equal to 1 and the rest doesn't make any sense .

Related

Why do I have an 'invalid column name' when I try to sum two columns with alias that contains a space? [duplicate]

I've create 3 computed columns as alias and then used the aliased columns to calculate the total cost. This is the query:
SELECT TOP 1000 [Id]
,[QuantityOfProduct]
,[Redundant_ProductName]
,[Order_Id]
,(CASE
WHEN [PriceForUnitOverride] is NULL
THEN [Redundant_PriceForUnit]
ELSE
[PriceForUnitOverride]
END
) AS [FinalPriceForUnit]
,(CASE
WHEN [QuantityUnit_Override] is NULL
THEN [Redundant_QuantityUnit]
ELSE
[QuantityUnit_Override]
END
) AS [FinalQuantityUnit]
,(CASE
WHEN [QuantityAtomic_Override] is NULL
THEN [Redundant_QuantityAtomic]
ELSE
[QuantityAtomic_Override]
END
) AS [Final_QuantityAtomic]
--***THIS IS WHERE THE QUERY CREATES AN ERROR***--
,([QuantityOfProduct]*[FinalPriceForUnit]*
([Final_QuantityAtomic]/[FinalQuantityUnit])) AS [Final_TotalPrice]
FROM [dbo].[ItemInOrder]
WHERE [IsSoftDeleted] = 0
ORDER BY [Order_Id]
The console returns this ERROR message:
Msg 207, Level 16, State 1, Line 55
Invalid column name 'FinalPriceForUnit'.
Msg 207, Level 16, State 1, Line 55
Invalid column name 'Final_QuantityAtomic'.
Msg 207, Level 16, State 1, Line 55
Invalid column name 'FinalQuantityUnit'.
If I remove the "AS [Final_TotalPrice]" alias computed column, no error occurs, but I need the total price. How can I solve this issue? It seems as the other aliases have not been created when the Final_TotalPrice is reached.
You can't use table aliases in the same select. The normal solution is CTEs or subqueries. But, SQL Server also offers APPLY. (Oracle also supports APPLY and other databases such as Postgres support lateral joins using the LATERAL keyword.)
I like this solution, because you can create arbitrarily nested expressions and don't have to worry about indenting:
SELECT TOP 1000 io.Id, io.QuantityOfProduct, io.Redundant_ProductName,
io.Order_Id,
x.FinalPriceForUnit, x.FinalQuantityUnit, x.Final_QuantityAtomic,
(x.QuantityOfProduct * x.FinalPriceForUnit * x.Final_QuantityAtomic / x.FinalQuantityUnit
) as Final_TotalPrice
FROM dbo.ItemInOrder io OUTER APPLY
(SELECT COALESCE(PriceForUnitOverride, Redundant_PriceForUnit) as FinalPriceForUnit,
COALESCE(QuantityUnit_Override, Redundant_QuantityUnit) as FinalQuantityUnit
COALESCE(QuantityAtomic_Override, Redundant_QuantityAtomic) as Final_QuantityAtomic
) x
WHERE io.IsSoftDeleted = 0
ORDER BY io.Order_Id ;
Notes:
I don't find that [ and ] help me read or write queries at all.
COALESCE() is much simpler than your CASE statements.
With COALESCE() you might consider just putting the COALESCE() expression in the final calculation.
You can't use an alias in the same select. What you can do is find the value in subquery and then use it outside in the expression (or may be repeated the whole case statement in your expression). Also, use COALESCE to instead of CASE.
select t.*,
([QuantityOfProduct] * [FinalPriceForUnit] * ([Final_QuantityAtomic] / [FinalQuantityUnit])) as [Final_TotalPrice]
from (
select top 1000 [Id],
[QuantityOfProduct],
[Redundant_ProductName],
[Order_Id],
coalesce([PriceForUnitOverride], [Redundant_PriceForUnit]) as [FinalPriceForUnit],
coalesce([QuantityUnit_Override], [Redundant_QuantityUnit]) as [FinalQuantityUnit],
coalesce([QuantityAtomic_Override], [Redundant_QuantityAtomic]) as [Final_QuantityAtomic]
from [dbo].[ItemInOrder]
where [IsSoftDeleted] = 0
order by [Order_Id]
) t;

SQL must appear in the GROUP BY clause or be used in an aggregate function

I have a SQL statement
sql = """
insert into metadata (code, code_map, has_property) (
select
code,
jsonb_agg(to_jsonb(new_code)) as code_map,
has_property
from data_to_data
where code is not null
group by 1
) on conflict (code) do update
set code_map = excluded.code_map;
"""
Previously the has_property field didn't exist and this was working fine. Now that I've added has_property, I am getting the error
column "data_to_data.has_property" must appear in the GROUP BY clause or be used in an aggregate function
I understand what this means, but I'm not sure how to fix the issue. The has_property field should be the same for any equivalent codes being inserted, so I'd just want to aggregate them into one Boolean.
Here is an example of the data
code, code_map, has_property
1, 2, True
1, 3, True
5, 6, False
5, 7, False
Any suggestion on how to accomplish this?
If the codes are the same, there is no harm in including it in the group by:
select code,
jsonb_agg(to_jsonb(new_code)) as code_map,
has_property
from data_to_data
where code is not null
group by code, has_property;
Alternatively, use an aggregation function:
select code,
jsonb_agg(to_jsonb(new_code)) as code_map,
bool_or(has_property) as has_property
from data_to_data
where code is not null
group by code;

Getting Error when using SQL With Common Table Expression (CTE)

I am new to SQL. I am trying to use SQL CTE but I keep getting the error:
Msg 102, Level 15, State 1, Line 16
Incorrect syntax near ')'.
I am using ms-sql and reading the following blog for guide.
This is my query
WITH parents(BranchCode, SOLD,BANKERSCOUNT, [TARGET]) AS
(
SELECT MS.ParentBranchCode,
SUM(NP.SOLD) SOLD,
SUM(NP.BANKERSCOUNT) BANKERSCOUNT,
SUM(NP.[TARGET]) [TARGET]
FROM NEDLLIFEPARTICIPATION NP
INNER JOIN m_Structure MS
ON MS.BranchCode = NP.BranchCode
GROUP BY MS.ParentBranchCode, NP.Year, NP.MONTH, NP.ProductId
)
Does this give you an error? If not then it might be that you simply have not included a select statement following your common table expression. This would explain why your error is showing an issue with the closing bracket, it is just telling you (if my assumption is right) that your CTE is not being used in a query (and therefore will not compile).
WITH parents(BranchCode, SOLD,BANKERSCOUNT, [TARGET]) AS
(
SELECT MS.ParentBranchCode,
SUM(NP.SOLD) SOLD,
SUM(NP.BANKERSCOUNT) BANKERSCOUNT,
SUM(NP.[TARGET]) [TARGET]
FROM NEDLLIFEPARTICIPATION NP
INNER JOIN m_Structure MS
ON MS.BranchCode = NP.BranchCode
GROUP BY MS.ParentBranchCode, NP.Year, NP.MONTH, NP.ProductId
)
select * from parents;

SQL Server : merge using Join on Source Table fails to bind

I am writing a SQL Server Merge statement but can't seem to get the syntax correct. Would someone please take a look to see where I'm going wrong?
Any help you can give is most appreciated.
What I have is two tables that I'd like to merge (w_materialmarketprices2 and d_component). My source (d_component) table requires me to do a join to a tax table (d_tax).
Everything works fine except for when I try to add the additional tax table into my join. The reason I need the tax table is because it contains a tax rate which I don't have in my d_component table (although I do have the corresponding tax code).
My comparison criteria between w_materialmarketprices2 and d_component includes the tax rate in the calculation.
Here's my code:
MERGE [DWH].[dbo].[w_materialmarketprices2] AS A
USING
(SELECT
[comp_code], [comp_desc], [comp_o_un], [comp_type],
[comp_ccy], [comp_tx], [comp_net_price], [comp_per],
[comp_doc_date], [comp_last_update], [comp_latest],
D.[tax_rate] AS TaxRate
FROM
[DWH].[dbo].[d_component]) AS B
INNER JOIN
[DWH].[dbo].[d_tax] AS D ON D.[tax_code] = B.[comp_tx]
ON
A.[mp_comp_code] = B.[comp_code] AND A.[mp_valid_date] = B.[comp_doc_date] AND B.[comp_net_price]>0 AND A.[mp_price_inc_vat] = ROUND(((B.[comp_net_price]/B.[comp_per])*(1+TaxRate),3) AND A.[mp_budget_actual] = 'PO Actual' AND B.[comp_type] ='P100' AND (left(B.[comp_code],1)='S' OR left(B.[comp_code],1)='R')
WHEN NOT MATCHED BY TARGET
THEN
INSERT ([mp_budget_actual], [mp_comp_code], [mp_comp_desc], [mp_unit], [mp_unit_qty], [mp_qualified_supplier], [mp_ccy], [mp_price_inc_vat], [mp_valid_date], [mp_last_update], [mp_latest])
VALUES ('PO Actual', B.[comp_code], B.[comp_desc], B.[comp_o_un], 1, 'Y', B.[comp_ccy], ROUND(((B.[comp_net_price]/B.[comp_per])*(1+TaxRate),3), B.[comp_doc_date], B.[comp_last_update], B.[comp_latest])
;
The error I'm getting is:
Msg 4145, Level 15, State 1, Line 20
An expression of non-boolean type specified in a context where a condition is expected, near ','.
Msg 102, Level 15, State 1, Line 23
Incorrect syntax near 'B'.
,D.[tax_rate] AS TaxRate shows up as underlined in red so I reckon the problem is something to do with that. I also get the message
The multi-part identifier "D.tax_rate" could not be bound
Thanks for your help in advance. Honkonger.
There is no reason to use a subquery in the USING clause, ie: don't put a SELECT in there:
MERGE [DWH].[dbo].[w_materialmarketprices2] AS A
USING
[DWH].[dbo].[d_component] AS B
INNER JOIN [DWH].[dbo].[d_tax] AS D ON D.[tax_code] = B.[comp_tx]
ON
A.[mp_comp_code] = B.[comp_code] .......

Why is my case statement not working with a calculation while using signed over punch?

I'm trying to write a query to go against "Signed Over Punch" using the following query:
SELECT
CASE when substring(MyField,16,1)='C' then cast(substring(MyField,9,7)+'0' AS decimal(20,2)*-1 FROM MyTable
Here's some sample data:
0000069A0000006C00000000#0000000#
From the above data, the position starts at 16 ("C") with a length of 1
And the other starts at position 9 (0) with a length of 7
But I keep getting this error:
Msg 102, Level 15, State 1, Line 139
Incorrect syntax near '*'.
Desired Output:
00000063 (The C = 3)
What am I doing wrong?
Please refer to this page for reference for signed over punch:
https://en.wikipedia.org/wiki/Signed_overpunch
You need to learn about operator precedence. This code:
[..snip..] then cast(substring(MyField,9,7)+'0' AS decimal(20,2)*-1
is executing as if it had been written
[..snip..] then cast(...) AS (decimal(20,2) * -1)
^------------------^
You're not multiplying the result of the cast, you're trying to mutiply the decimal(20,2), which is NOT a multiplicable value.
Try
then (cast(substring(MyField,9,7)+'0' AS decimal(20,2)) * -1
^------------------------------------------------^
instead.
Not sure if this will fix it or not, but you are missing a closing parenthesis. You are also missing the END statement I recommend indenting things like this to make it easier to spot these problems.
SELECT CASE
WHEN substring(MyField,16,1)='C'
THEN cast(substring(MyField,9,7)+'0' AS decimal(20,2))*-1
END
FROM MyTable
try so:
SELECT CASE when substring(MyField,16,1)='C' then cast(substring(MyField,9,7)+'0' AS decimal(20,2)) *-1 end FROM MyTable
The problems were a missing " ) " at the defore " *-1 " and a missing "end" to terminate the case when condition.
With these 2 fix the result for your example '0000069A0000006C00000000#0000000#' is -60.00.