SQL SERVER 2005 CASE WHEN THEN END - sql

I am running following query..
Select T1.* from T1
LEFT JOIN T2 ON T1.C1 = T2.C1
LEFT JOIN T3 ON T2.C3 = T3.C3
ORDER BY Case When T1.C1 = 'ABC' THEN 'XYZ' END AS COMMENTS
Its giving me Syntax error near AS. Unable to figure out the error.

You don't need the AS alias when using case in an order by
Select T1.* from T1
LEFT JOIN T2 ON T1.C1 = T2.C1
LEFT JOIN T3 ON T2.C3 = T3.C3
ORDER BY Case When T1.C1 = 'ABC' THEN 'XYZ' END

It's because you are trying to assign an alias to the ORDER BY clause - this is not allowed and I'm not sure what you want to achieve here?
You either need:
Select T1.* from T1
LEFT JOIN T2 ON T1.C1 = T2.C1
LEFT JOIN T3 ON T2.C3 = T3.C3
ORDER BY Case When T1.C1 = 'ABC' THEN 'XYZ' END
Or, if you want that CASE value to be returned in the SELECT as well, then you need:
Select T1.*, Case When T1.C1 = 'ABC' THEN 'XYZ' END AS COMMENTS
from T1
LEFT JOIN T2 ON T1.C1 = T2.C1
LEFT JOIN T3 ON T2.C3 = T3.C3
ORDER BY Case When T1.C1 = 'ABC' THEN 'XYZ' END
Also, again not sure of intention here so it depends, but you may need an ELSE on that CASE...
e.g.
ORDER BY CASE WHEN T1.C1 = 'ABC' THEN 'XYZ' ELSE T1.C1 END

Related

Conversion of Oracle join to Ansi join

I need to convert the following Oracle SQL to ANSI SQL.
Select t1.c1, t2.c2, t1.c3 from t1, t2 where
T1.c1=t2.c1(+) and
T1.c2=t2.c2(+) and
T1.c3=t2.c3 and
T1.c4=t2.c4 and
T1.c1='1'
This would be outer join if all columns in t2 had the (+) modifier.
That would look like:
Select t1.c1, t2.c2, t1.c3
from t1 left join
t2
on T1.c1 = t2.c1 and T1.c2 = t2.c2 and
T1.c3 = t2.c3 and T1.c4 = t2.c4
where T1.c1 = '1';
However, your version is an inner join, because some of the columns do need to match -- so there needs to be a matching row in the second table.
So, the real equivalent is just:
Select t1.c1, t2.c2, t1.c3
from t1 join
t2
on T1.c1 = t2.c1 and T1.c2 = t2.c2 and
T1.c3 = t2.c3 and T1.c4 = t2.c4
where T1.c1 = '1';
And the (+) is not relevant.

Subquery in Inner join - Multi-part identifer could not be bound

I have the following query and I am getting a multi-part identifier could not be bound exception. I realize why and my next thought was to use a CROSS APPLY, which didn't work. What I really need to do is join that subquery to make sure I get the most recent entry for a particular column.
Unfortunately, I've run out of ideas... How do I accomplish this query?
SELECT t1.*
FROM dbo.Table1 t1 (nolock)
INNER JOIN
(
SELECT TOP 1 t2_s.c1, t2_s.c2, t2_s.c4
FROM dbo.Table2 t2_s
WHERE t2_s.c1 = t1.c1
ORDER BY t2_s.dateStamped DESC
) t2
on t2.c1 = t1.c1
INNER JOIN dbo.Table3 t3
on t3.c1 = t2.c2 and t3.c2 = 1
WHERE t1.c2 = 'xxx'
Assuming you are using SQL Server, then CROSS APPLY should do what you want:
SELECT t1.*
FROM dbo.Table1 t1 (nolock) CROSS APPLY
(SELECT TOP 1 t2_s.c1, t2_s.c2, t2_s.c4
FROM dbo.Table2 t2_s
WHERE t2_s.c1 = t1.c1
ORDER BY t2_s.dateStamped DESC
) t2 INNER JOIN
dbo.Table3 t3
on t3.c1 = t2.c2 and t3.c2 = 1
WHERE t1.c2 = 'xxx';

Query optimization in SQL Server

SELECT
T2.Entity1Id, T1.Entity1Id
FROM
T1
FULL OUTER JOIN
T2 ON T1.c2 = T2.c2 AND T1.c1 = T2.c1 AND T1.c3 = 1
WHERE
((T1.c1 = 123 ) OR (T2.c1 = 123))
AND (T1.c3 = 1 OR T1.c3 IS NULL)
Above query is taking 12 seconds in SQL Server 2014, any idea to tune the query? There are indexes on C1,C2,C3 columns.
Observation: in the above query, when I remove a condition from OR (i.e.
SELECT
T2.Entity1Id, T1.Entity1Id
FROM
T1
FULL OUTER JOIN
T2 ON T1.c2 = T2.c2 AND T1.c1 = T2.c1 AND T1.c3 = 1
WHERE
(T1.c1 = 123) AND (T1.c3 = 1 OR T1.c3 IS NULL)
then it's returning results in 0 seconds.
Each table has around 500'000 records.
First, the final condition (T1.c3 = 1 OR T1.c3 IS NULL) is redundant. Given the join condition, these are the only possible values. So, the query is:
SELECT T2.Entity1Id, T1.Entity1Id
FROM T1 FULL OUTER JOIN
T2
ON T1.c2 = T2.c2 AND T1.c1 = T2.c1 AND T1.c3 = 1
WHERE (T1.c1 = 123 ) OR (T2.c1 = 123)
If this doesn't have good performance, consider breaking this into two queries:
SELECT T2.Entity1Id, T1.Entity1Id
FROM T1 LEFT JOIN
T2
ON T1.c2 = T2.c2 AND T1.c1 = T2.c1 AND T1.c3 = 1
WHERE T1.c1 = 123
UNION
SELECT T2.Entity1Id, T1.Entity1Id
FROM T2 LEFT JOIN
T1
ON T1.c2 = T2.c2 AND T1.c1 = T2.c1 AND T1.c3 = 1
WHERE T2.c1 = 123
Sometimes, the optimization of the separate subqueries is much better than the optimization for the full outer join.

SQL join using UNION ALL with some columns common and some outer

I would like to make the following join, which is some sort of UNION ALL in SQL. How to do it? Preferably how to do it by selecting all columns form t1 and t2 and declaring matching keys? I would like to avoid specifying column names if it is possible.
Update. I put some values in columns to be more specific. This is what I want:
Join 1
Probably I got answers for this:
Join 2
Use a full outer join, like so:
select *
from table1 t1
full outer join table2 t2
on t1.c4 = t2.c1 and t1.c5 = t2.c2
While SQL Server supports full outer joins, MySQL does not. This query can be rewritten in that situation as follows:
select *
from table1 t1
left outer join table2 t2
on t1.c4 = t2.c1 and t1.c5 = t2.c2
union
select *
from table1 t1
right outer join table2 t2
on t1.c4 = t2.c1 and t1.c5 = t2.c2
Based on your updated requirements, the form of this join specified above can be used with slight modifications like so:
select null,null,null,t.* from table1 s
right outer join table2 t on s.c4 = t.c1 and s.c5 = t.c2
union
select s.*,null,null from table1 s
left outer join table2 t on s.c4 = t.c1 and s.c5 = t.c2
Note that you will still need to include the literal value null in your select clause, once for each column that needs to be defaulted to null.
Demo
Use a FULL OUTER JOIN
Assuming C4 and C5 in your output example are from t2...
SELECT t1.C1, t1.C2, t1.C3, t2.C3, t2.C4
FROM t1
FULL OUTER JOIN t2 ON t1.C4 = t2.C1 AND t1.C5 = t2.C2

Joining 3 tables to get only two rows

I have three table I need to query table 1,2 and 3 and select C1 from Table 1 and C2 from table 2 and 3 respectively so that it would give result. Is there any way of getting this?
Yes:
select t1.c1, coalesce(t2.c2, t3.c2) c2
from Table1 t1
left join Table2 t2 on t1.c1 = t2.c1
left join Table3 t3 on t1.c1 = t3.c1
Try the following:
SELECT T1.C1, T2.C2
FROM T1
INNER JOIN T1.C1 = T2.C1
UNION ALL
SELECT T1.C1, T3.C2
FROM T1
INNER JOIN T1.C1 = T3.C1