How to write this T-SQL WHERE condition? - tsql

I've got two tables:
TableA
Col1
Col2
TableB
Col3
Col4
I want to join them together:
SELECT * from TableA join TableB ON (...)
Now, in place of ... I need to write an expression that evaluates to:
If Col3 is not null, then true iif Col1==Col3; otherwise
If Col3 is null, then true iif Col2==Col4
What would be the most elegant way to do this?

ON (Col1=Col3 OR (Col3 IS NULL AND Col2=Col4))
should do the trick (if Col3 is null, Col1=Col3 cannot evalutate to TRUE)

Try this:
SELECT *
FROM TableA
JOIN TableB
ON Col1 = Col3
OR (Col3 IS NULL AND Col2 = Col4)

Related

how to count the distinct rows from two tables using joins

I have two tables like
table1 table2
------------ ----------------
col1 col2 col1 col2
I need to count the distinct col1 from table1 if itis matching with table2 col1
note: table2 col1 also distinct
select count(distinct table1.col1)
from table1,table2
where table1.col1=table2.col1
As you select the distinct col of table1, and set the join, the col1 of table2 will also be selected distinctly.

T-SQL find differences

I found Jeff Smith's solution which is displaying differences between two tables:
SELECT MIN(TableName) as TableName, ID, COL1, COL2, COL3 ...
FROM
(
SELECT 'Table A' as TableName, A.ID, A.COL1, A.COL2, A.COL3, ...
FROM A
UNION ALL
SELECT 'Table B' as TableName, B.ID, B.COL1, B.COl2, B.COL3, ...
FROM B
) tmp
GROUP BY ID, COL1, COL2, COL3 ...
HAVING COUNT(*) = 1
ORDER BY ID
In my project I need to compare eg. col1 and col2 only, rest is used for another operations.
I tried to use
HAVING (COUNT(col1) = 1 and COUNT(col2) = 1)
but with no effect.
Could you please ptovide me solution which will do that?
Get the values of COL1 and COL2 in A that do not exist in B using EXCEPT:
SELECT COL1, COL2 FROM A
EXCEPT
SELECT COL1, COL2 FROM B
Use the results as a derived table to join them back to A and get all the columns:
SELECT 'A' AS SRC, A.COL1, A.COL2, A.COL3...
FROM (
SELECT COL1, COL2 FROM A
EXCEPT
SELECT COL1, COL2 FROM B
) AS diff
INNER JOIN A ON diff.COL1 = A.COL1 AND diff.COL2 = A.COL2
Similarly, use EXCEPT to get the values of COL1 and COL2 that exist only in B, and join the resulting set to B obtain complete rows accordingly.
Combine the two sets with UNION ALL:
SELECT 'A' AS SRC, A.COL1, A.COL2, A.COL3...
FROM (
SELECT COL1, COL2 FROM A
EXCEPT
SELECT COL1, COL2 FROM B
) AS diff
INNER JOIN A ON diff.COL1 = A.COL1 AND diff.COL2 = A.COL2
UNION ALL
SELECT 'B' AS SRC, B.COL1, B.COL2, B.COL3...
FROM (
SELECT COL1, COL2 FROM B
EXCEPT
SELECT COL1, COL2 FROM A
) AS diff
INNER JOIN B ON diff.COL1 = B.COL1 AND diff.COL2 = B.COL2
;
You are dropping the columns from the wrong place. You should drop it from the lists of columns instead of from the star:
SELECT MIN(TableName) as TableName, ID, COL1, COL2
FROM
(
SELECT 'Table A' as TableName, A.ID, A.COL1, A.COL2
FROM A
UNION ALL
SELECT 'Table B' as TableName, B.ID, B.COL1, B.COl2
FROM B
) tmp
GROUP BY ID, COL1, COL2
HAVING COUNT(*) = 1
ORDER BY ID
To keep the other columns in the result, you can use MIN (or friends) to keep them:
SELECT MIN(TableName) as TableName, ID, COL1, COL2, MIN(COL3), MIN(COL4), ...
FROM
(
SELECT 'Table A' as TableName, A.ID, A.COL1, A.COL2, A.COL3, A.COL4, ...
FROM A
UNION ALL
SELECT 'Table B' as TableName, B.ID, B.COL1, B.COL2, B.COL3, B.COL4, ...
FROM B
) tmp
GROUP BY ID, COL1, COL2
HAVING COUNT(*) = 1
ORDER BY ID
Note that this doesn't work very well for certain situations. If two rows are identical in the two tables (including IDs), then it will find it as a difference even though it's not. Also, in this version, if you have multiple rows where COL1 and COL2 are the same, then this doesn't work well either. I would join the two tables together for a more robust comparison.

Select from table where value can be null

I try to select from one table like this:
SELECT * FROM table1 where id=311
and date BETWEEN '2012-09-01' And '2012-09-09'
and col2='a'
and (col3 ='m'
or col3 ='n'
or col3=' ' )
ORDER BY date
In the table I have situation where col3 has values 'm', 'n' or null, but this select doesn't return rows where col3 has a null value
NULL is something other than ' ' use col3 is null
There is three-valued logic in database:
TRUE, FALSE, NULL(unknown)
col3 ='' is a true condition,
col3 is null is an unknown condition.
They are different.
so you must use
col3 is null
You may reference Wikipedia's "NULL" entry.
NULL is not equal to 'm' , 'n' or ' ' . NULL isn't even equal to NULL. Use:
SELECT * FROM table1 where id=311
and date BETWEEN '2012-09-01' And '2012-09-09'
and col2='a'
and (col3 ='m'
or col3 ='n'
or col3 IS NULL)
ORDER BY date
SELECT *
FROM table1
where
id=311
and date BETWEEN '2012-09-01' And '2012-09-09'
and col2='a'
and (
col3 ='m'
or col3 ='n'
or col3 is null
)
ORDER BY date
Here is a nice trick to avoid the OR list, and to also avoid the OR IS NULL:
SELECT *
FROM table1
WHERE id=311
AND zdate BETWEEN '2012-09-01' AND '2012-09-09'
AND col2='a'
AND COALESCE(col3, 'm') IN ('m', 'n' )
ORDER BY zdate
;

How to write One query for multiple groupings?

In the queries below, how can I make just one query that will give me the results, instead of making copies with diff groupings and unioning them?
If possible.
Thanks in advance!!
`create table #temp1 (col1 varchar(50), col2 varchar(50), col3 varchar(50), col4 varchar(50), col5 varchar(50), sumit int)
insert into #temp1 values('AEAMS','CE Europe', 'Belarus', 'Govt', 'Int Fed Gvt', 1)
insert into #temp1 values('AEAMS','CE Europe', 'Belarus', 'Govt', 'Public Lib', 1)
insert into #temp1 values('AEDS','Japan', 'Japan C', 'Acad', 'CollUnive', 1)
insert into #temp1 values('AEDS','Japan', 'Japan F', 'Acad', 'Med', 1)
insert into #temp1 values('A- Regular Databases','UK and Ireland', 'Ireland', 'School', 'HIGH SCHOOL', 1)
Select col1 CC, null GM, null Terr, null Mkt, null Seg, sum(sumit) SS
from #temp1
group by col1
Union
Select col1 CC, col2 GM, null Terr, null Mkt, null Seg, sum(sumit) SS
from #temp1
group by col1, col2
Union
Select col1 CC, col2 GM, col3 Terr, null Mkt, null Seg, sum(sumit) SS
from #temp1
group by col1, col2, col3
Union
Select col1 CC, col2 GM, col3 Terr, col4 Mkt, null Seg, sum(sumit) SS
from #temp1
group by col1, col2, col3, col4, col5
Try using WITH ROLLUP:
Select col1 CC, col2 GM, col3 Terr, col4 Mkt, null Seg, sum(sumit) SS
from #temp1
group by col1, col2, col3, col4, col5
with rollup
SQL Fiddle Example

How to filter sql duplicates?

My question: I want the records without duplicate, in the same table and in multiple tables? How can I proceed to do this in SQL?
Let me explain what I have tried:
Select distinct Col1, col2
from Table
where order id = 143
Output
VolumeAnswer1 AreaAnswer1 heightAnswer1
VolumeAnswer2 AreaAnswer1 heightAnswer2
VolumeAnswer3 AreaAnswer1 heightAnswer2
Expected Output
It shows the duplicate for the second table, but I need the output to be like:
VolumeAnswer1 AreaAnswer1 heightAnswer1
VolumeAnswer2 heightAnswer2
VolumeAnswer3
I need the same scenario for multiple tables, same duplicate I found for joins also. If it cannot be handled in SQL Server, how can we handle it in .Net? I used multiple select but they used to change it in single select. Each and every column should bind in dropdownlist...
Something like this might be a good place to start:
;with cte1 as (
Select col1, cnt1
From (
Select
col1
,row_number() over(Partition by col1 Order by col1) as cnt1
From tbltest) as tbl_sub1
Where cnt1 = 1
), cte2 as (
Select col2, cnt2
From (
Select
col2
,row_number() over(Partition by col2 Order by col2) as cnt2
From tbltest) as tbl_sub2
Where cnt2 = 1
), cte3 as (
Select col3, cnt3
From (
Select
col3
,row_number() over(Partition by col3 Order by col3) as cnt3
From tbltest) as tbl_sub3
Where cnt3 = 1
)
Select
col1, col2, col3
From cte1
full join cte2 on col1 = col2
full join cte3 on col1 = col3
Sql Fiddle showing example: http://sqlfiddle.com/#!3/c9127/1