SQL server syntax 1 - sql-server

with cte4 as
(
Select a.*,(a.ADV_ART+b.ADV_ART) as A_ART
from #Temp1 a
left join #Temp1 as b
on (a.CHAT_ID = b.CHAT_ID) and (a.N = b.N + 1)
where a.Category = 2 and b.Category = 2
)
UPDATE cte4
Set ADV_ART = A_ART;
In this query (a.ADV_ART+b.ADV_ART) is giving null. Please help.

If they are strings, try: coalesce(a.ADV_ART,'')+coalesce(b.ADV_ART,'')
If they are numbers, try: coalesce(a.ADV_ART,0)+coalesce(b.ADV_ART,0)
Whenever you add or concatenate a null value, the result is always null. One of your values is returning null, so you can use isnull(ValueThatMightBeNull,ReplaceWithThisValue)
or coalesce(ValueThatMightBeNull,ReplaceWithThisValue) to return a different value instead of null.
Reference:
isnull() - msdn
coalesce() - msdn

Related

Sql query with fetch by condition

Good day to you all. Faced with a problem and I am in a stupor, please help. You need to write an sql query according to the condition: where code = 2 and num = 2 then change the value, if code = 3 then take the record whose value code = 1
, a as (
select numberfn, street
from tbl
where code = 2
and nume = 2)
, b as (
select N from tbl where code = '3'
)
, actual as (
select b.value, a.N
from b
join a
on b.N = a.N
where b.code = '1'
union all
select st.value, st.N
from rreg st
join tbl b
on st.N = b.N
)
I tried to simplify it using case as well, but the second condition leads me to a dead end.
, actual as (
select N
, case when (code= 2 and num= 2)
then value
else .... (condition: select an entry for N where code = 1)
end value
from tbl
)
You have 2 requirements here, one is to update, the other is to select a value.
Separately they are:
UPDATE table
SET value = ??
WHERE code = 2 AND num = 2
And
SELECT * FROM table
WHERE code = 3 AND value = 1
(Where ?? = value you want to change the column value to.)
If you want both in one function, then they can be moved into a stored procedure.

Query works as expected, SSRS finds error?

This question was closed because someone thought it was the same issue as SSRS multi-value parameter using a stored procedure
But it is not. My report is not a stored procedure and thus, behaves differently. Also, this issue describes a result of getting no results if multi-valued params are used and that too is inaccurate for this scenario. So I'll try posting this again.
My report for the most part works. It is when I select more than one value from either of 2 specific params (#global, #manual) that I get this error:
Here is the SQL:
DECLARE #STATE VARCHAR(2) = 'mn'
,#START DATE = '6/1/2020'
,#END DATE = '7/1/2020'
,#GLOBAL VARCHAR(50) = 'indigent fee'
,#MANUAL VARCHAR(100) = '''misc charges'',''discount'''
DROP TABLE
IF EXISTS #customers
,#test
SELECT DISTINCT ch.amount
,ch.vehicle_program_id
,c.customer_id
,ch.customer_charge_id
,ch.charge_type
INTO #customers
FROM customer c
JOIN customer_charge ch(NOLOCK) ON c.customer_id = ch.customer_id
JOIN service_history sh(NOLOCK) ON sh.customer_id = c.customer_id
JOIN header h(NOLOCK) ON h.service_history_id = sh.service_history_id
WHERE ch.entry_date BETWEEN #START
AND #END
AND ch.price_trigger_id IN (
16
,15
)
AND ch.source_type = 1
AND sh.service_type = 5
AND h.is_duplicate = 0;
WITH CTE_global
AS (
SELECT DISTINCT ch.charge_type
,'global' AS type
FROM customer_charge ch
JOIN store s ON ch.store_id = s.store_id
JOIN address a ON a.id = s.address_id
JOIN locality l ON a.locality_id = l.id
WHERE l.region = #state
AND ch.price_trigger_id = 16
UNION ALL
SELECT 'None'
,'global'
)
,CTE_manual
AS (
SELECT DISTINCT ch.charge_type
,'manual' AS type
FROM customer_charge ch
JOIN store s ON ch.store_id = s.store_id
JOIN address a ON a.id = s.address_id
JOIN locality l ON a.locality_id = l.id
WHERE l.region = #state
AND ch.price_trigger_id = 15
UNION ALL
SELECT 'None'
,'manual'
)
SELECT DISTINCT c.last_name
,c.first_name
,vp.account_no
,cust.charge_type
,cust.amount
,sh.service_date
,s.store_name_short
,GLOBAL = g.charge_type
,manual = m.charge_type
INTO #test
FROM vehicle_program vp(NOLOCK)
JOIN vehicle v(NOLOCK) ON v.vehicle_id = vp.vehicle_id
JOIN service_history sh(NOLOCK) ON sh.vehicle_program_id = vp.program_id
AND service_type = 5
JOIN customer c(NOLOCK) ON v.customer_id = c.customer_id
AND c.customer_id = sh.customer_id
JOIN store s(NOLOCK) ON vp.current_store_id = s.store_id
JOIN #customers cust ON cust.customer_id = c.customer_id
AND cust.vehicle_program_id = sh.vehicle_program_id
JOIN customer_condition cc(NOLOCK) ON c.customer_id = cc.customer_id
JOIN customer_charge ch(NOLOCK) ON ch.customer_id = c.customer_id
JOIN service_charge sc ON sc.service_history_id = sh.service_history_id
AND sc.customer_charge_id = cust.customer_charge_id
JOIN header h(NOLOCK) ON h.service_history_id = sh.service_history_id
JOIN CTE_global g ON g.charge_type = ch.charge_type
JOIN CTE_manual m ON m.charge_type = ch.charge_type
WHERE cc.state_of_conviction = #state
AND sh.service_date BETWEEN #START
AND #END
AND h.is_duplicate = 0
SELECT *
FROM #test
WHERE GLOBAL IN (
CASE
WHEN #global IN ('None')
THEN charge_type
WHEN #global NOT IN ('None')
THEN #global
END
)
OR manual IN (
CASE
WHEN #manual IN ('None')
THEN charge_type
WHEN #manual NOT IN ('None')
THEN #manual
END
)
For clarity, the last bit in the query there is some logic to allow for these two params to be optional: so by selecting 'None' that param is rendered useless basically. It seems clear that the issue is with this last bit, specifically my WHERE clause using the CASE expression. When I remove that, I don't get the error, but I of course lose my logic. What's most confusing is that the error indicates an issue with a comma, but there's no comma in that part of the SQL?? Any help is going to be greatly appreciated.
Assuming users will only select 'None' from the list on it's own and never with another value then the following should work.
WHERE (GLOBAL IN (#Global) OR #Global = 'None')
AND
(manual IN (#manual) OR #manual = 'None')
this question was closed because someone thought it was the same issue
It is a dupe, but you kind of have to read between the lines in the other answers to apply it to this scenario. The point is that SSRS replaces multi-select parameters with delimited strings in the query body itself, and this transformation can lead either to unexpectedly getting no results, or in an illegal SQL query, depending on where the parameter marker appears in the original query.
I'll make it a bit clearer exactly what's going on. You can repro this behavior with this as your Data Set query:
drop table if exists #foo
create table #foo(charge_type varchar(200) , global varchar(200))
select *
from #foo
WHERE GLOBAL IN (
CASE
WHEN #global IN ('None')
THEN charge_type
WHEN #global NOT IN ('None')
THEN #global
END
)
And configure #global as a parameter that allows multi-select. When the user selects multiple values SSRS transforms the query into:
drop table if exists #foo
create table #foo(charge_type varchar(200) , global varchar(200))
select *
from #foo
WHERE GLOBAL IN (
CASE
WHEN N'a',N'b' IN ('None')
THEN charge_type
WHEN N'a',N'b' NOT IN ('None')
THEN N'a',N'b'
END
)
Which fails with An expression of non-boolean type specified in a context where a condition is expected, near ','.

Get value from the select statement on the row above in T-SQL

I want to get the value the previous select statement returned (similar to the ##IDENTITY function)
Code:
IF EXISTS (SELECT MyCriticalValue
FROM Units u
JOIN pUnit pu
ON pu.UnitID = u.UnitID
WHERE u.ChildUnitID = ( SELECT ps.UnitID
FROM psUnit ps
WHERE ps.Code = #CurrentCode)
AND pu.Type = 117
AND u.TypeID = 1 )
BEGIN
SET #CriticalValue = ##identity
END
I know that ##IDENTITY doesn't work since that's only for inserts. Is there a similar function to achieve what I want (which is to get "MyCriticalValue" from the select statement into the variable #CriticalValue without typing the entire SELECT statement twice).
EDIT:
Clarification: When I come to this point in my SQL script #CriticalValue is already set and I should ONLY overwrite it if the select-statement returns anything, so it should not be overwritten in any other case.
SELECT #CriticalValue = ISNULL(MyCriticalValue, #CriticalValue)
FROM Units u
JOIN pUnit pu
ON pu.UnitID = u.UnitID
WHERE u.ChildUnitID = (
SELECT ps.UnitID
FROM psUnit ps
WHERE ps.Code = #CurrentCode
)
AND pu.Type = 117
AND u.TypeID = 1;
IF #CriticalValue IS NOT NULL
...
I assumed that your query return one value.

Recursive triggers and error : subquery returned more than 1 value

I need your help !
I am working on sql server
1-- I created this trigger but it seems to be wrong...
CREATE TRIGGER [dbo].[chargeAZero]
ON [dbo].[situations_final]
after INSERT
AS
BEGIN
SET nocount ON
UPDATE sfinal
SET charge = 00
FROM inserted i
INNER JOIN situations_final sfinal
ON i.referencepiece = sfinal.referencepiece
AND i.ancienposte = sfinal.ancienposte
AND i.numerophase = sfinal.numerophase
AND i.datestrategie = sfinal.datestrategie
/*and i.Datecadence=sfinal.Datecadence*/
WHERE (SELECT sfinal.nouveauposte
FROM situations_final sfinal
INNER JOIN inserted i
ON i.referencepiece = sfinal.referencepiece
AND i.ancienposte = sfinal.ancienposte
AND i.numerophase = sfinal.numerophase
AND i.datestrategie = sfinal.datestrategie) IS
NULL
END
The error message is always the same: the subquery returned more than one value... I think I wrote my trigger correctly as I did with others that work fine.
2-- My second question is : Is it possible to make only one trigger recursive ?
3-- As you have noticed on my database on the table "Nomenclatures" (Bill of materials in english) I have 3 elements:
*codepiecemere: The component mother
*codepiecefille: the component child
* the quantity.
I give you an example of what I need :
Mother= A Child= B Quantity= 2
Mother= B Child= C Quantity= 3
I want a trigger to give me a result like that:
A 1 B 2 C 6=2*3 (the quantity needed of C to make 1 B).
Thank you very much
Here's a recursive query that solves the material aggregation problem.
Table definition
CREATE TABLE [dbo].[Material](
[Mother] [varchar](100) NOT NULL,
[Child] [varchar](100) NOT NULL,
[Quantity] [int] NOT NULL,
)
and the query:
WITH Result(mother, child, quantity)
AS
(
select * from material
union all
select M.mother, R.Child, M.quantity * R.Quantity as Quantity
from Result R INNER JOIN Material M ON M.Child = R.Mother
)
select * from result
You can see an example here: http://sqlfiddle.com/#!6/6dc64/1
UPDATE:
Sql fiddle is not working, I don't know why
UPDATE 2
Sql Fiddle is back! :-)
The is null is not normally used with subqueries. Try this:
where not exists (select 1
from SITUATIONS_Final sfinal inner join inserted i
on i.ReferencePiece=sfinal.ReferencePiece
and i.AncienPoste=sfinal.AncienPoste
and i.numerophase=sfinal.numerophase
and i.datestrategie=sfinal.datestrategie
)
This is assuming that the is null is testing for no values being returned, as opposed to a NULL value in sfinal.nouveauposte. If the latter:
where exists (select 1
from SITUATIONS_Final sfinal inner join inserted i
on i.ReferencePiece=sfinal.ReferencePiece
and i.AncienPoste=sfinal.AncienPoste
and i.numerophase=sfinal.numerophase
and i.datestrategie=sfinal.datestrategie
where sfinal.nouveauposte is null
)
EDIT:
Do you need the subquery at all?
UPDATE sfinal
SET charge = 00
FROM inserted i
INNER JOIN situations_final sfinal
ON i.referencepiece = sfinal.referencepiece
AND i.ancienposte = sfinal.ancienposte
AND i.numerophase = sfinal.numerophase
AND i.datestrategie = sfinal.datestrategie
WHERE sfinal.nouveauposte IS NULL;
I think the problem is that you are inserting more than one row in a single command, so the inserted table contains more than one row. As a consequence the sub query
SELECT sfinal.nouveauposte
FROM situations_final sfinal
INNER JOIN inserted i
ON i.referencepiece = sfinal.referencepiece
AND i.ancienposte = sfinal.ancienposte
AND i.numerophase = sfinal.numerophase
AND i.datestrategie = sfinal.datestrategie
contains more than one row too and cannot be compared to NULL that is a scalar value.
I am ambitious :D I tried to improve the script:
WITH RESULT (MOTHER, CHILD, QUANTITY)
as
(
select Mother, Child, CONVERT(Numeric(10,0), Quantity) as Quantity from bilangammestest
union all select M.mother, R.Child, CONVERT(Numeric(10,0), M.quantity * R.Quantity) as Quantity from Result R
INNER JOIN bilangammestest M ON M.Child = R.Mother
)
select * from result
where mother not in (select child from bilangammestest )
Here are the data I have on my table "Bilangammestest":
Z A 1
Z Y 1
A B 2
Y B 2
B C 3
Here are the result I get :
Z A 1
Z Y 1
Z C 6
Z C 6
Z B 2
Z B 2
Here is the Final result I want:
Z A 1
Z Y 1
Z C 12
Z B 4
I tried to do a 'sum' but I couldn't do it correctly :(

Case not working in Exists in Sql Server

I have a scenario where i have to check a variable for it's default value, and if it has i have to check EXISTS part conditionally with Table2 and if it does not have the default value, i have to check EXISTS part conditionally with Table3.
Below is a sample code:-
SELECT * FROM tbl1 WHERE EXISTS (SELECT CASE WHEN #boolVar = 0 THEN (SELECT 'X' FROM tbl2 WHERE tbl1.col1 = tbl2.col1) ELSE (SELECT 'X' FROM tbl3 where tbl1.col1 = tbl3.col1) END)
Demo query with constants for testing purpose: -
SELECT 1 WHERE EXISTS (SELECT CASE WHEN 1 = 0 THEN (SELECT 'X' WHERE 1=0)
ELSE (SELECT 'X' WHERE 1 = 2) END)
Note: - The above query always returning 1, even not a single condition is satisfying.
I know we can use OR operator for the same and any how we can achieve it, but i really want to know that in case both the tables have no rows satisfying their particular where clause, even it's returning all the rows from Table1.
I tried to explain the same with the demo query with constant values.
Please help.
When your query doesn't find any matching records, it will basically do:
SELECT 1 WHERE EXISTS (SELECT NULL)
As a row containing a null value is still a row, the EXISTS command returns true.
You can add a condition to filter out the null row:
SELECT * FROM tbl1 WHERE EXISTS (
SELECT 1 FROM (
SELECT
CASE WHEN #boolVar = 0 THEN (SELECT 'X' FROM tbl2 WHERE tbl1.col1 = tbl2.col1)
ELSE (SELECT 'X' FROM tbl3 where tbl1.col1 = tbl3.col1)
END AS Y
) Z
WHERE Y IS NOT NULL
)
Here's an alternative, just in case:
SELECT *
FROM Table1
WHERE EXISTS (
SELECT 1
FROM Table2
WHERE #var = #defValue
AND ... /* other conditions as necessary */
UNION ALL
SELECT 1
FROM Table3
WHERE #var <> #defValue
AND ... /* other conditions as necessary */
);

Resources