简体   繁体   中英

Oracle SQL: Use distinct(t1.field) in t2 of LEFT JOIN

I have a select statement which gives activities over a time range. Eg

Hour | Action | Count
---------------------
 00  | a1     | 23
 00  | a2     | 48
 01  | a1     | 16
 02  | null   | null
 03  | a1     | 5
 04  | a2     | 2

You see that thanks to the grouping which yields this result, there is no count for hour 01, action 02 and so on. What I want is the following:

Hour | Action | Count
---------------------
 00  | a1     | 23
 00  | a2     | 48
 01  | a1     | 16
 01  | a2     | 0
 02  | a1     | 0
 02  | a2     | 0
 03  | a1     | 5
 03  | a2     | 0
 04  | a1     | 0
 04  | a2     | 2

To do that I was thinking of determining the distinct values for row Action and then left join this with the same table. This would be something like this in SQL code:

select distinct(t2.action) as action 
from t2 as t1 
left join (select hour, action, count from <whatever to get the table>) as t2 
  on t1.action = t2.action

But if I do so, I understandibly get the error that the table t2 is not valid inside the select statement of t1.

Please help me with any advices to get this done. But I don't want to do the distinct on the original table (it has like 50 million entries).

Thanks in advance!

you can you an outer join + partition clause:

select hours.hour, t2.action, nvl(t2.count, 0)
  from (select distinct hour from t2) hours
       left outer join (select * from t2) t2
       partition by (t2.action)
                    on hours.hour = t2.hour
 where t2.action is not null
 order by hour, action;

or if you wanted to generate the hours 0-23 regardless of if the rows were in the table/view:

with hours as (select to_char(rownum-1, 'fm00') r from dual connect by level <= 24)
select hours.r, t2.action, nvl(t2.count, 0)
  from hours
       left outer join (select * from t2) t2
       partition by (t2.action)
                    on hours.r = t2.hour
 where t2.action is not null
 order by r, action;

fiddle: http://sqlfiddle.com/#!4/27a40/1

You need to add group by in your inner query and remove () around distinct. This works for me - similar to your query only w/out count:

SELECT distinct rm.user_id as user_id  -- rm.user_id comes from inner query
  FROM Readings r 
 LEFT JOIN  
 (
  SELECT r2.user_id, r2.reading_time, r2.x, r2.y
  FROM Readings r2
  ) rm   
 ON rm.user_id=r.user_id 
/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM