Get Distinct From Multiple Similar Tables - sql

I have this query to join a couple tables and get distinct values, it looks something like this:
SELECT DISTINCT [TrackingCode]
,[Opponent]
,CONCAT([TrackingCode], ' | ', [Opponent]) AS RowName
,[MultiYrEvent]
,[Identifier]
FROM [BUDGET_FY2014].[dbo].[TrackingCodes]
INNER JOIN
(
SELECT *
FROM [BUDGET_FY2014].[dbo].[Transactions]
WHERE Report='2377010003'
) AS T
ON T.EventCode LIKE CAST(TrackingCodes.TrackingCode AS nvarchar(20))+'%'
ORDER BY TrackingCode ASC
It works fine. However, I've got multiple Transactions tables with the same schema for the first and second previous years relative to the Transactions table, and I'd like to see distinct values from all three tables. So for example, if I copy/paste this query and change [Transactions] to [Transactions_Yr1] or [Transactions_Yr2], then I get the data I want from those tables. But, I want to combine the three. If I try to join them all, I get no results returned. I sort of understand why this doesn't work, but I don't know where to go from here:
SELECT DISTINCT [TrackingCode]
,[Opponent]
,CONCAT([TrackingCode], ' | ', [Opponent]) AS RowName
,[MultiYrEvent]
,[Identifier]
FROM [BUDGET_FY2014].[dbo].[TrackingCodes]
INNER JOIN
(
SELECT *
FROM [BUDGET_FY2014].[dbo].[Transactions]
WHERE Report='2377010003'
) AS T
ON T.EventCode LIKE CAST(TrackingCodes.TrackingCode AS nvarchar(20))+'%'
INNER JOIN
(
SELECT *
FROM [BUDGET_FY2014].[dbo].[Transactions_Yr1]
WHERE Report='2377010003'
) AS T1
ON T1.EventCode LIKE CAST(TrackingCodes.TrackingCode AS nvarchar(20))+'%'
INNER JOIN
(
SELECT *
FROM [BUDGET_FY2014].[dbo].[Transactions_Yr2]
WHERE Report='2377010003'
) AS T2
ON T2.EventCode LIKE CAST(TrackingCodes.TrackingCode AS nvarchar(20))+'%'
ORDER BY TrackingCode ASC
Any advice would be appreciated!

Try use UNION ALL clausele, e.g.:
SELECT DISTINCT [FILDS]
FROM (
SELECT *
FROM [BUDGET_FY2014].[dbo].[Transactions]
WHERE Report='2377010003'
UNION ALL
SELECT *
FROM [BUDGET_FY2014].[dbo].[Transactions_Yr1]
WHERE Report='2377010003'
UNION ALL
SELECT *
FROM [BUDGET_FY2014].[dbo].[Transactions_Yr2]
WHERE Report='2377010003'
)
ORDER BY TrackingCode ASC

have you tried unioning your transaction tables together?
Reference: https://msdn.microsoft.com/en-us/library/ms180026.aspx
SELECT DISTINCT [TrackingCode]
,[Opponent]
,CONCAT([TrackingCode], ' | ', [Opponent]) AS RowName
,[MultiYrEvent]
,[Identifier]
FROM [BUDGET_FY2014].[dbo].[TrackingCodes]
INNER JOIN
(
SELECT * FROM(
SELECT *
FROM [BUDGET_FY2014].[dbo].[Transactions]
WHERE Report='2377010003'
) AS T
ON T.EventCode LIKE CAST(TrackingCodes.TrackingCode AS nvarchar(20))+'%'
Union
(
SELECT *
FROM [BUDGET_FY2014].[dbo].[Transactions_Yr1]
WHERE Report='2377010003'
) AS T1
ON T1.EventCode LIKE CAST(TrackingCodes.TrackingCode AS nvarchar(20))+'%'
Union
(
SELECT *
FROM [BUDGET_FY2014].[dbo].[Transactions_Yr2]
WHERE Report='2377010003'
) AS T2
ON T2.EventCode LIKE CAST(TrackingCodes.TrackingCode AS nvarchar(20))+'%'
)
ORDER BY TrackingCode ASC

Related

Select rows with a duplicate ID but different value in another column

I have a table like this
I would like to select the Itemid that occurs more than once with a different Rate with group by Masterid
The output should be something like:
You might try the following:
SELECT masterid, detailid, itemid, rate FROM mytable
WHERE (masterid, detailid, rate) IN
(
SELECT masterid, detailid, rate FROM mytable t
JOIN mytable o ON o.masterid = t.masterid
AND o.detailid = t.detailid AND o.rate <> t.rate
GROUP BY t.masterid, t.detailid, t.rate
HAVING COUNT(*) >= 2
)
The inner join within the sub-query assures only rows appearing that have an unequal counter part. Alternatively you might add another sub-query condition to the outer query:
AND EXISTS
(
SELECT * FROM mytable o
WHERE o.masterid = t.masterid AND o.detailid = t.detailid AND o.rate <> t.rate
)
I believe you are looking for a query like below
select t1.* from t t1
join
(
select masterid,itemid
from t
group by masterid,itemid
having count(distinct rate )>1
)t2
on t1.masterid=t2.masterid and t1.itemid=t2.itemid
order by masterid,detailid
and here's a working db fiddle
Try following code:
Select masterid, detailid, rate, count(*) as count from Mytable
group by masterid, detailid, rate
having count(*) > 1

How to convert Oracle SQL query into datalake(Impala)?

I have one Oracle SQL query in the below format how I can proceed to convert this into Impala:-
SELECT
Some_Columns
FROM
(
SELECT * FROM
(
SELECT
Some_more_columns
FROM
Main_table
LEFT JOIN t1 on codn_1 = cond_2
....
....
Some more left joins
.....
WHERE
some_filters
)
PIVOT(
count(*) for column_x in (some_column)
)
) T
ORDER BY 2,3

Subqueries with different universes

I have an Oracle DB and I need to run a select with sub selects, however, none of them share the same table universe, therefore, I would need to do something like this:
SELECT (
SELECT COUNT(*)
FROM user_table
) AS tot_user,
(
SELECT COUNT(*)
FROM cat_table
) AS tot_cat,
(
SELECT COUNT(*)
FROM course_table
) AS tot_course
I know this is possible at other databases but I need something like this for Oracle.
Can someone help?
To make this work in oracle, add from dual to the end:
SELECT (SELECT COUNT(*)
FROM user_table
) AS tot_user,
(SELECT COUNT(*)
FROM cat_table
) AS tot_cat,
(SELECT COUNT(*)
FROM course_table
) AS tot_course
FROM dual;
A database independent way of writing the query is:
select tot_user, tot_cat, tot_course
from (SELECT COUNT(*) as tot_user
FROM user_table
) u cross join
(SELECT COUNT(*) as tot_cat
FROM cat_table
) c cross join
(SELECT COUNT(*) as tot_course
FROM course_table
) ct;

SQL query to merge 2 tables with additional conditions?

I have 2 identical tables: user_id, name, age, date_added.
USER_ID column may contain multiple duplicate IDs.
Need to merge those 2 tables into 1 with the following condition.
If there are multiple records with identical 'name' for the same user then need to keep only the LATEST (by date_added) record.
This script will be used with MSSQL 2005, but would also appreciate if somebody comes up with version that does not use ROW_NUMBER(). Need this script to reload a broken table once, performance is not critical.
example:
table1:
1,'john',21,01/01/2010
1,'john',15,01/01/2005
1,'john',71,01/01/2001
table2:
1,'john',81,01/01/2007
1,'john',15,01/01/2005
1,'john',11,01/01/2008
result:
1,'john',21,01/01/2010
UPDATE:
I think that I've found my own solution. It is based on an answer for my previous question given by Larry Lustig and Joe Stefanelli.
with tmp2 as
(
SELECT * FROM table1
UNION
SELECT * FROM table2
)
SELECT * FROM tmp2 c1
WHERE (SELECT COUNT(*) FROM tmp2 c2
WHERE c2.user_id = c1.user_id AND
c2.name = c1.name AND
c2.date_added >= c1.date_added) <= 1
Could you please help me to convert this query to the one without 'WITH' clause?
Here's a variant of #Andomar's answer:
; with all_users as
(
select *
from table1 u1
union all
select *
from table2 u2
)
, ranker as (
select *,
rank() over (partition by userid order by recordtime) as [r]
)
select * from ranker where [r] = 1
Just in the interests of giving a different approach...
WITH distinctlist
As (SELECT user_id,
name
FROM table1
UNION
SELECT user_id,
name
FROM table2)
SELECT C.*
FROM distinctlist d
CROSS APPLY (SELECT TOP 1 *
FROM (SELECT TOP 1 *
FROM table1
WHERE user_id = d.user_id
AND name = d.name
ORDER BY date_added DESC
UNION ALL
SELECT TOP 1 *
FROM table1
WHERE user_id = d.user_id
AND name = d.name
ORDER BY date_added DESC) T
ORDER BY date_added DESC) C
You could use not exists, like:
; with all_users as
(
select *
from table1 u1
union all
select *
from table2 u2
)
select *
from all_users u1
where not exists
(
select *
from all_users u2
where u1.name = u2.name
and u1.record_time < u2.record_time
)
If the database doesn't support CTE's, expand all_users in the two places it is used.
P.S. If there are only three columns, and no more, you could use an even simpler solution:
select name
, MAX(record_time)
from (
select *
from table1 u1
union all
select *
from table2 u2
) sub
group by
name

Self-join of a subquery

I was wondering, is it possible to join the result of a query with itself, using PostgreSQL?
You can do so with WITH:
WITH subquery AS(
SELECT * FROM TheTable
)
SELECT *
FROM subquery q1
JOIN subquery q2 on ...
Or by creating a VIEW that contains the query, and joining on that:
SELECT *
FROM TheView v1
JOIN TheView v2 on ...
Or the brute force approach: type the subquery twice:
SELECT *
FROM (
SELECT * FROM TheTable
) sub1
LEFT JOIN (
SELECT * FROM TheTable
) sub2 ON ...
Do you mean, the result of a query on a table, to that same table. If so, then Yes, it's possible... e.g.
--Bit of a contrived example but...
SELECT *
FROM Table
INNER JOIN
(
SELECT
UserID, Max(Login) as LastLogin
FROM
Table
WHERE
UserGroup = 'SomeGroup'
GROUP BY
UserID
) foo
ON Table.UserID = Foo.UserID AND Table.Login = Foo.LastLogin
Yes, just alias the queries:
SELECT *
FROM (
SELECT *
FROM table
) t1
JOIN (
SELECT *
FROM table
) t2
ON t1.column < t2.other_column