apply order by after combining results from two tables? - sql

I have two tables with same columns. am using oracle 10g.
TableA
------
id status
---------------
1 W
2 R
TableB
------
id status
---------------
1 W
3 S
I have two tables. i get results from both the tables using UNION as below.
select id, status
from TableA
union
select id, status
from TableB
order by status;
if i do that, is order by applied for both the queries?
My requirement is first it has to combine the results then it has to apply order by...
How can i do that?
Thanks!

Given the data you've shown, your query will return this:
ID STATUS
-- ------
2 R
3 S
1 W
That's because UNION will return only unique rows and the (1, 'W') row has a duplicate.
If you want to include all rows, even duplicates, use UNION ALL instead of UNION:
select id, status
from TableA
union all
select id, status
from TableB
order by status;
With UNION ALL your query will return this:
ID STATUS
-- ------
2 R
3 S
1 W
1 W

Try the following query
select id, status
from (select id, status from TableA
union select id, status from TableB)
order by status

select id, status
from TableA
union
select id, status
from TableB
order by 2; -- status

I think you need Distinct :
Select Distinct id, status
from (
select id, status from TableA
union
select id, status from TableB)
order by status

Related

Select number of IDs in more than one table (from three tables)

I need the count of this:
select distinct ID
from (
select ID from A
union all
select ID from B
union all
select ID from C
) ids
GROUP BY ID HAVING COUNT(*) > 1;
but I have no idea how to do it.
Use a subquery:
select count(*)
from (select ID
from (select ID from A
union all
select ID from B
union all
select ID from C
) ids
group by ID
having count(*) > 1
) i;
SELECT DISTINCT is almost never needed with GROUP BY and definitely not in this case.
You just want to find the id that appear 2 more times in the A,B,C table, the SQL is below:
select count(1) from (
select
id,
count(1)
from
(
select ID from A
union all
select ID from B
union all
select ID from C
)
group by id having(count(1)>1)
) tmp

Oracle Getting latest value from the other table

I have two tables, table1 contains old values and table2 contains latest values, I want to show latest value in table1 but I do not have anything which tells me this is the latest value in table2.
for example
Table1
CID-----PID-----RID
CT1-----C-------R1
CT2-----C-------R2
CT3-----C-------R3
CT4-----C-------R4
Table2
CID-----PID----RID
CT1-----A-------R1
CT1-----C-------R11
CT2-----C-------R2
CT3-----A-------R3
CT4-----A-------R4
The condition is I have to give priority to value C in case both values (A and C) exist also it's RID changes so need to get that also in output table, for the same CID and for unique value I will simple replace it in table1 from table2, so output will be like this
Table3
CID-----PID----RID
CT1-----C-------R11
CT2-----C-------R2
CT3-----A-------R3
CT4-----A-------R4
I may be missing something, but isn't this simply:
select cid, max(pid)
from table2
group by cid;
If you want whole records, use a ranking with ROW_NUMBER instead:
select cid, pid, rid
from
(
select cid, pid, rid, row_number() over (partition by cid order by pid desc) as rn
from table2
)
where rn = 1;
You can also use case expressions for ranking, e.g.:
(partition by cid order by case pid when 'C' then 1 when 'A' then 2 else 3 end) as rn
UPDATE: Now that you've finally explained what you are after ...
You want more or less the second query I gave you above. Only that you want data from both tables, which you can get with UNION ALL. You can easily give each row a rank on the way:
table2 PIM C => rank #1
table2 PIM A => rank #2
table1 rank #3
Then again take the row with the best rank:
select cid, pid, rid
from
(
select cid, pid, rid, row_number() over (partition by cid order by rnk) as rn
from
(
select cid, pid, rid, case when pid = 'C' then 1 else 2 end as rnk from table2
union
select cid, pid, rid, 3 as rnk from table1
)
)
where rn = 1;

SQL - How to Order By in UNION query

Is there a way to union two tables, but keep the rows from the first table appearing first in the result set? However orderby column is not in select query
For example:
Table 1
name surname
-------------------
John Doe
Bob Marley
Ras Tafari
Table 2
name surname
------------------
Lucky Dube
Abby Arnold
Result
Expected Result:
name surname
-------------------
John Doe
Bob Marley
Ras Tafari
Lucky Dube
Abby Arnold
I am bringing Data by following query
SELECT name,surname FROM TABLE 1 ORDER BY ID
UNION
SELECT name,surname FROM TABLE 2
The above query is not keeping track of order by after union.
P.S - I dont want to show ID in my select query
I am getting ORDER BY Column by joining tables. Following is my real query
SELECT tbl_Event_Type_Sort_Orders.Appraisal_Event_Type_ID AS Appraisal_Event_Type_ID , ISNULL(tbl_Appraisal_Event_Types.Appraisal_Event_Type_Display_Name, 'UnCategorized') AS Appraisal_Event_Type_Display_Name
INTO #temptbl
FROM tbl_Event_Type_Sort_Orders
INNER JOIN tbl_Appraisal_Event_Types
ON tbl_Event_Type_Sort_Orders.Appraisal_Event_Type_ID = tbl_Appraisal_Event_Types.Appraisal_Event_Type_ID
WHERE 1=1
AND User_Name='abc'
ORDER BY tbl_Event_Type_Sort_Orders.Sort_Order
SELECT * FROM #temptbl
UNION
SELECT DISTINCT (tbl_Appraisal_Event_Types.Appraisal_Event_Type_ID) AS Appraisal_Event_Type_ID , ISNULL(tbl_Appraisal_Event_Types.Appraisal_Event_Type_Display_Name, 'UnCategorized') AS Appraisal_Event_Type_Display_Name
FROM tbl_Appraisal_Event_Types
INNER JOIN tbl_Appraisal_Events
ON tbl_Appraisal_Event_Types.Appraisal_Event_Type_ID = tbl_Appraisal_Events.Event_Type_ID
INNER JOIN tbl_Appraisals
ON tbl_Appraisal_Events.Appraisal_ID = tbl_Appraisal_Events.Appraisal_ID
WHERE 1=1
AND ((tbl_Appraisals.Assigned_To_Staff_User) = 'abc' OR (tbl_Appraisals.Assigned_To_Staff_User2) = 'abc' OR (tbl_Appraisals.Assigned_To_Staff_User3) = 'abc')
Put a UNION ALL in a derived table. To keep duplicate elimination, do select distinct and also add a NOT EXISTS to second select to avoid returning same person twice if found in both tables:
select name, surname
from
(
select distinct name, surname, 1 as tno
from table1
union all
select distinct name, surname, 2 as tno
from table2 t2
where not exists (select * from table1 t1
where t2.name = t1.name
and t2.surname = t1.surname)
) dt
order by tno, surname, name
You can use a column for the table and one for the ID to order by:
SELECT x.name, x.surname FROM (
SELECT ID, TableID = 1, name, surname
FROM table1
UNION ALL
SELECT ID = -1, TableID = 2, name, surname
FROM table2
) x
ORDER BY x.TableID, x.ID
You can write as below, if you are ok with duplicate data then please use UNION ALL it will be faster:
SELECT NAME, surname FROM (
SELECT ID,name,surname FROM TABLE 1
UNION
SELECT ID,name,surname FROM TABLE 2 ) t ORDER BY ID
this will order the first row sets first then by anything you need
(haven't tested the code)
;with cte_1
as
(SELECT ID,name,surname,1 as table_id FROM TABLE 1
UNION
SELECT ID,name,surname,2 as table_id FROM TABLE 2 )
SELECT name, surname
FROM cte_1
ORDER BY table_id,ID
simply use a UNION clause with out order by.
SELECT name,surname FROM TABLE 1
UNION
SELECT name,surname FROM TABLE 2
if you wanted to order first table use the below query.
;WITH cte_1
AS
(SELECT name,surname,ROW_NUMBER()OVER(ORDER BY Id)b FROM TABLE 1 )
SELECT name,surname
FROM cte_1
UNION
SELECT name,surname
FROM TABLE 2

How to exclude some (not all) record that has same values

After query table A using first query, I have these records:
pID cID code
1 1 A
1 1 B
1 1 B
1 1 B
After query table B using second query, I have one record:
pID cID code
1 1 B
1 1 B
I want table A exclude the records of table B. The result is:
pID cID code
1 1 A
1 1 A
How can I do that? Hope u could help me. thanks.
Updating...
Sorry for the example to make you confuse
If I got these record from second table:
pID cID code
1 1 B
Then the result I want is (exclude one record):
pID cID code
1 1 A
1 1 B
1 1 B
you try GROUP BY function in your Query
example :
select pID,cID,code from table group by code
using EXCEPT and row_number() to generate a unique no
;with cte1 as
(
select *, rn = row_number() over (partition by pID, cID, code order by pID, cID, code)
from query1
),
cte2 as
(
select *, rn = row_number() over (partition by pID, cID, code order by pID, cID, code)
from query2
)
select *
from cte1
except
select *
from cte2
Based on your question, which I think you want to delete the records from B which occur more than once in A:
first select all records from A which are not there in B and then union them 1 distinct records which are there in both A and B:
select * from A
except
select * from B
union all
select distinct *
from
(select a.pid, a.cid, a.code
from
A
inner join
B
on a.pid=b.pid and a.cid=b.cid and a.code=b.code)
Just use EXCEPT. How ever your desired output is wrong as 1 1 B also the same record from TableB
SELECT * FROM TABLE_A
EXCEPT
SELECT * FROM TABLE_B
Refer this Link
If your case NOt all But some then.
Simply you can use DISTINCT
As per the UPdate in Question (From what I understood)
SELECT DISTINCT * FROM TABLE_A
UNION ALL
SELECT * FROM TABLE_B

how to repeat each row twice

I have a requirement for a report and I would like my sql query to repeat each row twice.
Example :
**Table 1**
Id Name
1 Ab
2 Cd
3 Ef
I want to write a query which outputs the following :
1 Ab
1 Ab
2 Cd
2 Cd
3 Ef
3 Ef
Is there a way I can do it ?
I cannot think of anything except using union
Select Id, name from Table1 union select Id, name from Table1
You can use a union all. A union will not work, because it will eliminate duplicates. Another way is a cross join:
select id, name
from table1 t1 cross join
(select 1 as n union all select 2) n;
You can also use UNION ALL, put them under CTE (Common Table Expression) and Order By Id:
WITH CTE AS
(
SELECT Id, Name FROM Table_1
UNION ALL
SELECT Id, Name FROM Table_1
)
SELECT Id, Name
FROM CTE
ORDER BY Id;
As this will reorder them and stacked them as duplicates
Solution will be like this:
select Id, name from Table1
union all
select Id, name from Table1