table1, table2 and table3 have different columns but all have an OrderDate column. I want to get a result set of rows from all 3 tables, and I want the final result set to be sorted by OrderDate.
( select * from table1 LEFT join table2 on 0=1 LEFT join table3 on 0=1
where somedate <= table1.orderdate )
union all
( select * from table1 RIGHT join table2 on 0=1 LEFT join table3 on 0=1
where somedate <= table2.orderdate )
union all
( select * from table1 RIGHT join table2 on 0=1 RIGHT join table3 on 0=1
where somedate <= table3.orderdate )
This works, but I want this result set to be ordered by orderdate, so I add:
order by case when table1.orderdate is not null then table1.orderdate
when table2.orderdate is not null then table2.orderdate
else table3.orderdate end
SQL Server returns the error "ORDER BY items must appear in the select list if the statement contains a UNION, INTERSECT or EXCEPT operator."
If I replace
select *
by
select *, table1.orderdate, table2.orderdate, table3.orderdate
I get the same error.
Huh? Thanks.
Try This
Select * from
(( select * from table1 LEFT join table2 on 0=1 LEFT join table3
where somedate <= table1.orderdate )
union all
( select * from table1 RIGHT join table2 on 0=1 LEFT join table3
where somedate <= table2.orderdate )
union all
( select * from table1 RIGHT join table2 on 0=1 RIGHT join table3
where somedate <= table3.orderdate )) A
Order by A.orderdate
I solved the problem using a Common Table Expression, here is what I did:
WITH JoinedTable as
(
( select table1.col1 as t1col1, table2.col2 as t1col2 [etc...]
from table1 LEFT join table2 on 0=1 LEFT join table3 on 0=1
where somedate <= table1.orderdate )
union all
( select table1.col1 as t1col1, table2.col2 as t1col2 [etc...]
from table1 RIGHT join table2 on 0=1 LEFT join table3 on 0=1
where somedate <= table2.orderdate )
union all
( select table1.col1 as t1col1, table2.col2 as t1col2 [etc...]
from table1 RIGHT join table2 on 0=1 RIGHT join table3 on 0=1
where somedate <= table3.orderdate )
)
select *, case when t1orderdate is not null then t1orderdate
when t2orderdate is not null then t2orderdate
else t3orderdate end
AS DateForOrderingResultSet
from JoinedTable order by DateForOrderingResultSet
The
table1.col1 as t1col1, table2.col2 as t1col2 [etc...]
which replaces * cannot be avoided if table1, table2, table3 have identical column names (for example ID) otherwise SQL Server throws an error saying JoinedTable.ID is ambiguous: it has no way to know if this means table1.ID or table2.ID or table3.ID.
Related
I have a query as follows:
select --this select should always give me 1 record
tbl1.Id, tbl1.Name, tbl1.Address, tbl2.relNo,
CASE WHEN tbl3.Comments IS NOT NULL THEN 1 ELSE 0 END AS 'Required'
from
table1 tbl1
inner join
table2 tbl2 on tbl2.Id = tbl1.Id
left join -- This left join table gives me 5 records for one instance
(select
R.Id, C.Comments
from
tblC C
inner join
tblR R on R.Id = C.id) tbl3 on tbl3.Id = tbl2.Id
I want to write a CASE statement on the rows my left join is giving to check for null value as above and my final select query always return only 1 row. Is there a way to check if all five Comments Column values from my left join be checked for NULLs in the above query?
I would take a shortcut an use a COUNT() OVER PARTITION
CASE WHEN COUNT(*) OVER (PARTITION BY tbl3.Id) =0 THEN 0 ELSE 1 END AS 'Required'
You would have to DISTINCT your output above. Another option would be to GROUP BY and filter in the HAVING clause.
select --this select should always give me 1 record
tbl1.Id, tbl1.Name, tbl1.Address, tbl2.relNo
From table1 tbl1
inner join table2 tbl2 on tbl2.Id = tbl1.Id
left join (-- This left join table gives me 5 records for one instance
SELECT R.Id,
C.Comments
FROM tblC C
INNER JOIN tblR R on R.Id = C.id
) tbl3 on tbl3.Id = tbl2.Id
GROUP BY
Id, Name, Address, relNo
HAVING
COUNT(*) = 5
Is this what you're looking for?
(CASE WHEN (select count(tbl3.id) FROM tbl3 WHERE tbl3.Comments IS NULL) then 1 else 0 end) as 'RequiredVal'
select --this select should always give me 1 record
tbl1.Id, tbl1.Name, tbl1.Address, tbl2.relNo,
CASE WHEN tbl3.Comments IS NOT NULL THEN 1 ELSE 0 END AS 'Required'
, (CASE WHEN (select count(tbl3.id) FROM tbl3 WHERE tbl3.Comments IS NULL) then 1 else 0 end) as 'RequiredVal'
From table1 tbl1
inner join table2 tbl2 on tbl2.Id = tbl1.Id
left join (-- This left join table gives me 5 records for one instance
SELECT R.Id,
C.Comments
FROM tblC C
INNER JOIN tblR R on R.Id = C.id
) tbl3 on tbl3.Id = tbl2.Id
I have 3 tables like master and 2 child tables . I am using join condition but did not get as expected client needs.
Query:
select * from(
select a.id as mid,b.id,b.val from ##mastertable a right join ##table1 b
on a.id=b.id ) as c inner join ##table2 d on c.mid=d.id
Kindly provide any other way to get proper result.
Try:
Select a.id, b.id, b.val
From (mastertable a
Right Join table1 b
On a.id = b.id)
Inner Join table2 d
On a.id = d.id;
This should work :
select * from (
(select master.id from master_table) master
LEFT OUTER JOIN
(select table1.id, table1.value from table_1) table1
ON
master.id = table1.id
FULL OUTER JOIN
(select table2.id, table2.value from table_2) table2
ON
table1.id = table2.id
AND
table1.val = table2.val
)
;
Try below: https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=2b58625961c444997829abb45d40417b
select * from master m inner join
(select table2.id as id1, table2.value as val1, table1.value as val2, table1.id as id2
from table2 left join table1
on table1.id=table2.id and table1.value=table2.value)x on m.id=x.id1
This will be same as you expected
select
m.id, t1.id, t1.value, t2.id, t2.value
from
m
left join
t1
on
m.id = t1.id
left join
t2
on
t1.id = t2.id and t1.value = t2.value
order by m.id, t1.value
here M is your master table, T1 is table1 and t2 is table2
Table 1 2 columns: ID, Name
Table 2 2 columns: ID, Name
What is a query to show names from Table 1 that are not in table 2? So filtering out all the names in table 1 that are in table 2 gives the result query. Filtering is on ID not name.
Select * from table1
left join table2 on table1.id = table2.id
where table2.id is null
This should perform better than the left join...is null version. See here and here for comparisons.
select t1.id, t1.name
from table1 t1
where not exists(select null from table2 t2 where t2.id = t1.id)
Use this query
select
t1.*
from table1 t1
left outer join table2 t2
on t1.id=t2.id
where t2.id is null
this works by joining everything in t1 to whatever exists in t2. the where clause filters out all of the records that don't exist in t2.
SELECT Table1.ID, Table1.Name, Table2.ID
FROM Table1 LEFT OUTER JOIN Table2 ON Table1.ID = Table2.ID
WHERE Table2.ID IS NULL
I think that should do it.
Try like this:
select t1.*
from table1 as t1
where t1.id not in
(select distinct t2.id from table2 as t2);
I need to build an SQL statement to delete from certain table the records that match another select statement.
In Teradata we use
delete from table1
where (col1, col2) in (
select col1,col2
from table2
)
While in SQL Server it's not allowed to have more than 1 column in the WHERE..IN clause. I thought I can use the WITH clause:
with tempTable(col1,col2) as (
select col1,col2
from table2
)
delete from table1
where table1.col1 = tempTable.col1
and table1.col2 = tempTable.col2
How to use WITH..DELETE clause? Is there another way?
This should do it:
DELETE Table1
from Table1 t1
inner join tempTable t2
on t2.Col1 = t1.Col1
and t2.Col2 = t1.Col2
First build a query that selects the rows you need:
SELECT t1.*
FROM [Table1] t1
INNER JOIN [Table2] t2 ON t1.[col1] = t2.[col1] AND t1.[Col2]=t2.[Col2]
Test it to make sure it returns exactly the rows you want to delete. Then turn it into a delete statement by changing the "SELECT" to "DELETE" and removing the column list:
DELETE t1
FROM [Table1] t1
INNER JOIN [Table2] t2 ON t1.[col1] = t2.[col1] AND t1.[Col
delete from table1 t1 where exists
(
select 1 from table2 t2 where t1.col1 = t2.col1 and t1.col2 > t2.col2
)
with tempTable(col1,col2) as (
select col1,col2
from table2
)
delete table1 from tempTable
where table1.col1 = tempTable.col1
and table1.col2 = tempTable.col2
This works for me
WITH CTE AS
(
SELECT TOP 50000 *
from v020101hist order by data
)
DELETE FROM CTE
I need to fetch a column from table2, if row exists, if not return it as null.
If i use ,case when it fetches only matched rows between table1 and table2.
If i use left outer join it fetches all the rows from table1 even though
condition table1.code='A'
So i need ,some thing like this.
select table1.id,
if(row exist in table2 for query(table2.relation_type_id=55 and table1.id=table2.related_id)
then
return table2.parent_id
else
null
as parent_id,
table1.description,
from table1,table2 where table1.code='A'
SELECT table1.id, table2.parent_id as parent_id
FROM table1
LEFT OUTER JOIN table2 ON (table1.id = table2.related_id)
WHERE table1.code = 'A';
EDIT based on comment :
SELECT table1.id, sub.parent_id as parent_id
FROM table1
LEFT OUTER JOIN (select parent_id,related_id from table2 where relation_type_id =55) sub ON (table1.id = sub.related_id)
WHERE table1.code = 'A';
Have you tried a sub-query?
select table1.id,
(select table2.parent_id from table2 where table2.relation_type_id=55 and table2.related_id=table1.id) parent_id,
table1.description,
from table1 where table1.code='A'