select id, shelfno, sectionno,
iif(tableA.shelfno = tableB.promono, itemdesc + ' Best Sale Right Now!', itemdesc),
salesprice
from tableA
left join tableB on tableA.shelfno = tableB.promono
The query works as it is, however, I wonder if there's a better way of doing/writing this. I was thinking of using a outer apply, but it's not looking that would work.
EDIT: To be clearer, I'm trying to remove the IIF (same thing as CASE) from the SELECT statement.
No CASE, no IIF, as requested...
select id, shelfno, sectionno,
COALESCE(promodesc, itemdesc),
salesprice
from tableA A
OUTER APPLY (
SELECT
itemdesc + ' Best Sale Right Now!' AS promodesc
FROM tableA
INNER JOIN tableB on tableA.shelfno = tableB.promono
WHERE id = A.id
) B
You could use CASE WHEN.
SELECT id
,shelfno
,sectionno
,itemdesc + CASE WHEN tableA.shelfno = tableB.promono
THEN ' Best Sale Right Now!'
ELSE '' END
,salesprice
FROM tableA
LEFT JOIN tableB
ON tableA.shelfno = tableB.promono
Is this what you're looking for?
case
tableB.promono is null then itemdesc
else itemdesc + ' Best Sale Right Now!'
end
This assumes that the left join is only being used in your if and no other columns are being used from tableB (which would be clearer if you aliased them all):-
SELECT id, shelfno, sectionno, itemdesc + CASE WHEN exists(
select *
from tableB
where tableB.promono = tableA.shelfno) THEN ' Best Sale Right Now!'
ELSE '' END as itemdesc,
salesprice
FROM tableA
or in Sql Server 2012:-
SELECT id, shelfno, sectionno, itemdesc + iif(exists(
select *
from tableB
where tableB.promono = tableA.shelfno),' Best Sale Right Now!','') as itemdesc,
salesprice
FROM tableA
Related
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
I have two tables
Table 1, columns: A, B, C
Table 2, columns: A, D, E
I want to select all from table 1 with an additional field added.
If the contents of string column table_1.A exists in table_2.A, then TRUE, if not then FALSE.
I'd love to tell you what I've tried, but nothing is coming close. I can do this with a SELECT CASE statement, but I can't figure out how to select all at the same time.
Thanks
Try using CASE
SELECT
table1.A,
table1.B,
table1.C,
CASE WHEN table2.A IS NULL THEN 'FALSE' ELSE 'TRUE' END
FROM
table1
LEFT OUTER JOIN
table2
ON table1.A = table2.A
SELECT T1.*, IIF(T2.D IS NULL, 'FALSE', 'TRUE')
FROM Table1 T1
LEFT JOIN Table2 T2 ON T2.A LIKE '%' + T1.A + '%'
You need a left outer join and them compare both tables using the case when columnab is not null then true else false
This would give you only one row per record in Table1.
SELECT Table1.*,
ISNULL([Found],'False') [Found]
FROM Table1
OUTER APPLY (
SELECT TOP 1
'True' AS [Found]
FROM Table2
WHERE Table2.A LIKE '%' + Table1.A + '%'
)
I have 2 name columns from table1.name and table2.name. I have names in table1.name like "Alex Testing" and in table2.name it's "Alexander Testing". I have the table do some other tricky stuff but it doesn't recognize that Alex and Alexander are the same people so it will not include the name in my report. I was wondering if there was a way I could get these 2 to inner join by first name or even by last name, like if another table had the same first name but different last name?
I've tried:
SELECT
Table1.[Name], Table2.[Time],
CASE WHEN myvariables here then 0 ELSE 1 END AS columnB
INTO NewTable
FROM
Table1 INNER JOIN Table2
ON Table1.[Name] LIKE ('%' + Table2.Name + '%')
however it still does not work, it wont recognize Alex's name.
I've also tried:
SELECT
Table1.[Name], Table2.[Time],
CASE WHEN myvariables here THEN 0 ELSE 1 END as columnB
INTO NewTable
FROM
Table1 INNER JOIN Table2
ON Table1.[Name] LIKE CONCAT('%',"Table2.Name", '%')
Try:
SELECT
Table1.[Name], Table2.[Time],
CASE WHEN myvariables here then 0 ELSE 1 END AS columnB
INTO NewTable
FROM
Table1 INNER JOIN Table2
ON SUBSTRING(Table1.[Name], CHARINDEX(' ', Table1.[Name]) + 1, LEN(Table1.[Name])) = SUBSTRING(Table2.[Name], CHARINDEX(' ', Table2.[Name]) + 1, LEN(Table2.[Name]))
If you have large volume tables you may want to use subqueries and select directly lastnames, and then use a join on lastnames.
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.
I am not sure if I've missed to search properly, but I couldn't get the exact question as mine
This is something similar but not exact
https://stackoverflow.com/questions/11533636/determining-which-table-to-join-to
Actually I want to decide with which table to join based on the parameter passed to stored procedure, case when didn't work
Kind of
select * from Table1
left join (case when #Parameter<>NULL Then Table2 else Table3 end) final
on Table1.Col1 = final.Col1
Table2 and Table3 has same structure
I can think of a few of options:
1: IF ... ELSE
IF #Parameter IS NULL
SELECT *
FROM T1
INNER JOIN T2 ON T1.ID = T2.ID
ELSE
SELECT *
FROM T1
INNER JOIN T3 ON T1.ID = T3.ID
2: Dynamic T-SQL
DECLARE #SQL NVARCHAR(MAX);
SELECT #SQL = N'SELECT *
FROM T1
INNER JOIN ' + CASE WHEN #Parameter IS NULL THEN N'T2 t' ELSE N'T3 t' END
+ N' ON T1.ID = t.ID';
EXEC sp_executesql #SQL;
3: UNION ALL and subquery.
SELECT *
FROM T1
INNER JOIN
(
SELECT *
FROM T2
WHERE #Parameter IS NULL
UNION ALL
SELECT *
FROM T3
WHERE #Parameter IS NOT NULL
) t ON T1.ID = t.ID
For this last one you'd have to check the plan the optimiser creates to see if it's OK performance wise.
It seems like you're looking for code reuse, so maybe option 2 is your best one. T-SQL doesn't really lend itself to this sort of polymorphism but you can use workarounds in some cases.
Taking a step back, one question to ask is, if the tables have the same structure, maybe you should just use one table? Then you could use #Parameter to just filter the rows you require instead of trying to create dynamic queries.
It's also worth noting that in situations like this you could handle the code-generation at the application layer with ORMs and the like.
Try this:
select *
from (
select data.*,
case when selection=1 then t1.ExtraField
when selection=2 then t2.ExtraField
when selection=3 then t3.ExtraField
else NULL
end as ExtraField
from data
left join t1 on t1.key = data.key and selection=1
left join t2 on t2.key = data.key and selection=2
left join t3 on t3.key = data.key and selection=3
) T
where ExtraField is not NULL
Done with this
SELECT PA.`module_id` as usertype, PA.module_pk_id, (
CASE PA.`module_id`
WHEN '0'
THEN pea.`name`
ELSE CONCAT(u.`first_name`, " ",u.`last_name`)
END
) as name
FROM `placements_approvers` PA
LEFT JOIN
placements_external_approvers pea
ON
PA.module_pk_id = pea.placement_external_approver_id AND PA.`module_id` = 0
LEFT JOIN
users u
ON
PA.module_pk_id = u.user_id AND PA.`module_id` != 0
WHERE PA.placement_id = '494' AND PA.approver_type = 1