Use CASE or REPLACE for my conditional Query - sql-server

I have 2 tables on which join is there.
for second table TableB i am fetching both id and post.
SELECT a.id,
a.NAME,
b.id,
b.post
FROM tableA a
INNER JOIN tableB b
ON a.bid = b.id
But in one case b.id=3 i have post ='manager' but i have to show post='associate manager'. i cannot change table values but only query.
I am currently using replace .
SELECT a.id,
a.NAME,
b.id,
replace(b.post, 'manager', 'associate manager')
FROM tableA a
INNER JOIN tableB b
ON a.bid = b.id
Should i switch to case or this is correct.
Regards,

Use Case Statement
SELECT a.id,
a.NAME,
b.id,
CASE
WHEN b.id = 3 THEN 'associate manager'
ELSE post
END
FROM tableA a
INNER JOIN tableB b
ON a.bid = b.id

Related

SQL multi-part identifier can't be bound in SELECT

Is it possible to add a case using a column from other tables than first in the from section?
I can't use anything like C.code or Y.anything in the SELECT part:
SELECT
fromTableA, fromTableA, fromTableA,
CASE
WHEN fromTableA = anyValue THEN 'is_ok'
WHEN B.fromTableB = anyValue THEN 'couldnt.be.bound'
WHEN fromTableB = anyValue THEN 'invalid.column.name'
END AS X
FROM
(SELECT fromTableA,
SUM(fromTableA),
CASE WHEN A.fromTableA = 'anything' THEN 'still ok'
WHEN C.fromTableC = 'allowed' THEN 'no problem'
FROM tableA A
JOIN tableB B ON A.id = B.id
JOIN tableC C ON C.id = B.id
Having SUM(fromTableA) > 0
) AS Y
Edit: What I need is to use columns from table B or C in the outer Select ( I just can't remove the inner select because i would lost cases and aggregation operations there are in the inner select).
The following should be all you need, a derived table here doesn't accomplish anything.
select A.Cols...,
case
when A.col1 = anyValue then 'is_ok'
when B.Col1 = anyValue then 'couldnt.be.bound'
when B.Col2 = anyValue then 'invalid.column.name'
end as X
from tableA A
join tableB B on A.id = B.id
join tableC C on C.id = B.id;

How to compare data any field of two table in SQL Server?

I have two tables with same columns.
Table A have ID, Name, Des, Status and
Table B have ID, Name, Des, Status.
I want to compare data any field of Table B with Table A, except column ID because same.
As same picture above, when FETCH data of Table B, detect data of ID ID001 and ID003 not same, idea of my mind same
IF (SELECT COUNT (SELECT * FROM TABLE A RIGHT JOIN TABLE B ON A.ID = B.ID) != 0)
BEGIN
PRINT 'BLAH BLAH, NOT SAME'
END
If you have idea or solution, share for me, Thank you so much.
You can use CHECKSUM or BINARY_CHECKSUM:
SELECT a.*, b.*
FROM TableA a INNER JOIN TableB b ON b.ID = a.ID
WHERE CHECKSUM(b.Name, b.Des, b.Status) <> CHECKSUM(a.Name, a.Des, a.Status)
See also this link. It should be faster then multiple OR conditions.
IF (SELECT COUNT(*)
FROM TableA a INNER JOIN TableB b ON b.ID = a.ID
WHERE BINARY_CHECKSUM(b.Name, b.Des, b.Status)
<> BINARY_CHECKSUM(a.Name, a.Des, a.Status)
>0
PRINT 'Not the same.'
Since it is not too much clear how do you want to show your differences, this is one approach:
SELECT A.ID,
(CASE WHEN A.Name <> B.Name THEN 'Diff Name' ELSE '') NameCompare,
(CASE WHEN A.Des <> B.Des THEN 'Diff Des' ELSE '') DESCompare,
(CASE WHEN A.Status <> B.Status THEN 'Diff Status' ELSE '') StatusCompare
FROM A
INNER JOIN B
ON A.ID = B.ID
This is a simple join
To get all different rows, you can say:
select a.*, b.*
from TableA a inner join TableB b on b.ID = a.ID
where b.Name <> a.Name or b.Des <> a.Des or b.Status <> a.Status

SQL Server Conditional JOIN two tables

I have 3 Tables:
TableA(IDRem, IDPed, IDOP)
TableB(IDOP, IDPed)
TableC(IDPed, InvoiceDate)
I need a select to JOIN the records of TableA and TableC, but there are two possible conditions:
IF IDPed on TableA IS NOT NULL, then join directly to TableC by IDPed
ID IDPed on TableA IS NULL, then join to TableB by IDOp, and then join TableB to TableC by IDPed
So far i try this:
SELECT
TableA.*
,(CASE WHEN TableC.InvoiceDate IS NULL
THEN TableC2.InvoiceDate
ELSE TableC.InvoiceDate
END) AS InvoiceDate
FROM
TableA
LEFT JOIN TableC on TableA.IDPed = TableC.IDPed
LEFT JOIN TableB on TableB.IDOp = TableA.IDOp
INNER JOIN TableC as TableC2 on TableC2.IDPed = TableB.IDPed
The problem with this is that every field o tableA I want to include in the select I need to do a case...when to determine if the origin is tableA or TableA2.
Is there a better way of doing this? Thanks!
For complex joins you are better served in TSQL using cross apply:
When should I use Cross Apply over Inner Join?
select IDRem, IDPed, IDOP from TableA a
cross apply(
select IDOP, IDPed from TableB binner
where a.IDop = binner.IDop
) b
cross apply(
select IDPed, InvoiceDate cinner
where b.IDPed = cinner.IDPed
) c
where ...
Strictly psuedo-code but should give you a start.
You could try doing both JOINs and use UNION ALL
Edit: As pointed out in the comment by Vladimir Baranov, there's no need to check if a.IdPed IS NULL on the first SELECT since if it is, the JOIN would return no rows.
SELECT
a.*,
c.InvoiceDate
FROM TableA a
INNER JOIN TableC c ON c.IdPed = a.IdPed
UNION ALL
SELECT
a.*,
c.InvoiceDate
FROM TableA a
INNER JOIN TableB b ON b.IdOp = a.IdOP
INNER JOIN TableC c ON c.IdPed = b.IdPed
WHERE a.IdPed IS NULL

If statement within an inner join

Is there a way to have an if statement determine whether a join is necessary or not?
I need this because there are multiple foreign keys in the data I querying. if any of the foreign keys are null I need to change the SQL statement. I would like to write one statement that can be aware of any null values.
This is what I would like to do...
select a.*,b.* from table1 a inner join table2 b on a.id = b.id
if a.InspectorID is not null
{inner join table3 c on a.InspectionID = c.id}
else do nothing...
try this out...
select a.*,b.* from table1 a inner join table2 b on a.id = b.id
left join table3 c on a.InspectionID = c.id
where a.InspectorID is null or a.InspectionID = c.id
I am not sure, if you can conditionally join tables, but the "if" statement in t-sql is calles
case.
What about using union
select a.*,b.*
from table1 a
inner join table2 b on a.id = b.id
inner join table3 c on a.InspectionID = c.id
union all
select a.*,b.*
from table1 a
inner join table2 b on a.id = b.id
where a.InspectionID is null
If I understand correctly, you could use:
select a.*,b.*,c.fields
from table1 a inner join table2 b on a.id = b.id
left join table3 c on a.InspectionID = c.id
where a.InspectionID IS NOT NULL
Use dynamic sql. For detail about dynamic sql go through:
http://exacthelp.blogspot.in/2013/02/writing-dynamic-sql-queries-in-sql.html

Applying outer layer that wrapping two select statement

I have two query which has successfully inner join
select t1.countResult, t2.sumResult from (
select
count(column) as countResult
from tableA join tableB
on tableA.id = tableB.id
group by name
)t1 inner join (
select
sum(column) as sumResult
from tableA
join tableB
on tableA.id = tableB.id
group by name
)t2
on t1.name= t2.name
The above query will return me the name and the corresponding number of count and the sum. I need to do a comparison between the count and sum. If the count doesnt match the sum, it will return 0, else 1. And so my idea was implementing another outer layer to wrap them up and use CASE WHEN. However, I've failed to apply an outer layer just to wrap them up? This is what I've tried:
select * from(
select t1.countResult, t2.sumResult from (
select
count(column) as countResult
from tableA join tableB
on tableA.id = tableB.id
group by name
)t1 inner join (
select
sum(column) as sumResult
from tableA
join tableB
on tableA.id = tableB.id
group by name
)t2
on t1.name= t2.name
)
Alright the problem can be solved by simply assigning a name to the outer layer.
select * from(
select t1.countResult, t2.sumResult from (
select
count(column) as countResult
from tableA join tableB
on tableA.id = tableB.id
group by name
)t1 inner join (
select
sum(column) as sumResult
from tableA
join tableB
on tableA.id = tableB.id
group by name
)t2
on t1.name= t2.name
) as whatever //SQL Server need a name to wrap
Hope it will help any newbie like me
Ok, so far you have selected everything your first select has generated (kinda useless, but a start for what you want ;) )
SELECT CASE
WHEN countresult=sumresult THEN 'Equal'
ELSE 'Not'
END
FROM ( --your join select --
)
I don't have any sample data to test this so can just go on your code.
Your queries for t1 & t2 look identical - why don't you just do a sum & count in 1 step?
SELECT COUNT(column) AS countResult
,SUM(column) AS sumResult
FROM tableA INNER JOIN tableB
ON tableA.id = tableB.id
GROUP BY name
Also, as you mention you are a newb - read up on Common Table Expressions in SQL Server.
Before SQL 2005 you had to write these convoluted queries within queries within...
Get into the habit of using CTEs now.

Resources