I'm making a webpage user access log table in BigQuery.
But I don't know how agg log with exit_time.
I want recent 5 view page log array.
If view page log is less than 5, the array is shorter.
plz teach me.
USER_EXIT_LOG AS (
SELECT
['A','A','B'] AS user_id,
[1000,2000,1000] AS exit_time
),
VIEW_PAGE_LOG AS (
SELECT
['A','A','A','A','A','B','B'] AS user_id,
['a','b','c','d','e','a','b'] AS view_page_id,
[800,900,1800,1900,1950,800,900] AS time
)
USER_EXIT_LOG
| user_id | exit_time |
| -------- | --------- |
| A | 1000 |
| A | 2000 |
| B | 1000 |
VIEW_PAGE_LOG
| user_id | view_page_id | view_time |
| -------- | ----------- | --------- |
| A | a | 800 |
| A | b | 900 |
| A | c | 1800 |
| A | d | 1900 |
| B | a | 800 |
| B | b | 900 |
WHAT I WANT
| user_id | exit_time | view_page_array |
| ------- | --------- | --------------- |
| A | 1000 | [b,a] |
| A | 2000 | [e,d,c] |
| B | 1000 | [b,a] |
Consider below
select u.user_id, exit_time,
array_agg(view_page_id order by view_time desc limit 5) as view_page_array
from (
select user_id, exit_time,
ifnull(lag(exit_time + 1) over(partition by user_id order by exit_time), 0) start_time
from `project.dataset.USER_EXIT_LOG`
) u
join `project.dataset.VIEW_PAGE_LOG` v
on u.user_id = v.user_id
and view_time between start_time and exit_time
group by user_id, exit_time
If applied t sample data in your question
with `project.dataset.USER_EXIT_LOG` as (
select 'A' user_id, 1000 exit_time union all
select 'A', 2000 union all
select 'B', 1000
), `project.dataset.VIEW_PAGE_LOG` as (
select 'A' user_id, 'a' view_page_id, 800 view_time union all
select 'A', 'b', 900 union all
select 'A', 'c', 1800 union all
select 'A', 'd', 1900 union all
select 'A', 'e', 1950 union all
select 'B', 'a', 800 union all
select 'B', 'b', 900
)
the output is
Related
Sample date in the table:
+--------+---------+---------+--------------+-----------+------------+---+
| School | Class | Student | Student desc | Section | Date | |
+--------+---------+---------+--------------+-----------+------------+---+
| ABC | Grade 2 | Stud 1 | AAA | Mango | 5/12/2015 | 1 |
| DEF | Grade 2 | Stud 1 | AAA | Mango | 12/25/2018 | |
| DEF | Grade 2 | Stud 1 | AAA | Orange | 9/8/2016 | |
| GHI | Grade 3 | Stud 2 | BBB | Apple | 12/28/2016 | 2 |
| JKL | Grade 3 | Stud 2 | BBB | Pear | 12/19/2016 | |
| ABC | Grade 2 | Stud 3 | CCC | Guava | 12/28/2016 | 3 |
| GHI | Grade 3 | Stud 4 | DDD | StarFruit | 9/8/2018 | 4 |
+--------+---------+---------+--------------+-----------+------------+---+
Ideally mapping should be 1 student is only get assigned to one section in a class.
I need to build the query to fetch the data to meet below requirement:-
Irrespective of the School need to show the distinct data for those students which get assigned to multiple sections within same class.
+--------+---------+---------+--------------+----------+------------+
| School | Class | Student | Student desc | Section | Date |
+--------+---------+---------+--------------+----------+------------+
| DEF | Grade 2 | Stud 1 | AAA | Mango | 12/25/2018 |
| DEF | Grade 2 | Stud 1 | AAA | Orange | 9/8/2016 |
| GHI | Grade 3 | Stud 2 | BBB | Apple | 12/28/2016 |
| JKL | Grade 3 | Stud 2 | BBB | Pear | 12/19/2016 |
+--------+---------+---------+--------------+----------+------------+
Below is the query that provides the correct data if school information is fetched:
select distinct a.class
,a.student
,a.Stud desc
,a.section
,to_date(max(a.date),'MM-DD-YYYY')"Date"
from Table1 a,
( select class
,student
,count(distinct section) cot
from Table1 c
where 1=1
and class is not null
and incoming_qty >= 1
group by class
,student
Having count(distinct section) > 1
) b
where 1=1
and a.class = b.class
and a.student=b.student
and b.cot > 1
and b.class is not null
and a.incoming_qty_new >= 1
group by a.class,a.student,a.Stud desc,a.section
order by a.class,a.student,a.Stud desc,a.section;
But query not working as per expectation while trying to fetch the school detail.
Please suggest.
Here is example of analytic functions usage for your data. Try to extend it for your specific case.
WITH t(School, Class, Student, StudentDesc, SectionName, Dates) AS
(
SELECT 'ABC','Grade 2','Stud 1','AAA','Mango',date'2015-05-12' FROM dual UNION ALL
SELECT 'DEF','Grade 2','Stud 1','AAA','Mango',date'2018-12-25' FROM dual UNION ALL
SELECT 'DEF','Grade 2','Stud 1','AAA','Orange',date'2016-09-08' FROM dual UNION ALL
SELECT 'GHI','Grade 3','Stud 2','BBB','Apple',date'2016-12-28' FROM dual UNION ALL
SELECT 'JKL','Grade 3','Stud 2','BBB','Pear',date'2016-12-19' FROM dual UNION ALL
SELECT 'ABC','Grade 2','Stud 3','CCC','Guava',date'2016-12-28' FROM dual UNION ALL
SELECT 'GHI','Grade 3','Stud 4','DDD','StarFruit',date'2018-09-08' FROM dual
)
SELECT *
FROM (
SELECT t.*,
COUNT(DISTINCT SectionName) OVER (PARTITION BY Class, Student) AS cntStudentSections,
ROW_NUMBER() OVER (PARTITION BY Class, Student ORDER BY Dates) AS StudentRowNumber
FROM t
)
WHERE cntStudentSections > 1 AND StudentRowNumber = 1;
You can use analytic functions:
select t1.*
from (select t1.*,
count(*) over (partition by class, student, section) as cnt
from table1 t1
) t1
where cnt >= 2;
I'm currently blocked on an complex request... (with a join) :
I have this table "DATA":
order | product
----------------
1 | A
1 | B
2 | A
2 | D
3 | A
3 | C
4 | A
4 | B
5 | Y
5 | Z
6 | W
6 | A
And this table "DICO":
order | couple | first | second
-------------------------------
1 | A-B | A | B
2 | A-D | A | D
3 | A-C | A | C
4 | A-B | A | B
5 | Y-Z | Y | Z
6 | W-A | W | A
I would like to obtain, on one line :
order | count | total1stElem | %1stElem | total2ndElem | %1ndElem
------------------------------------------------------------------
A-B | 2 | 5 | 40% | 2 | 100%
A-D | 1 | 5 | 20% | 1 | 100%
A-C | 1 | 5 | 20% | 1 | 100%
Y-Z | 1 | 1 | 100% | 1 | 100%
W-A | 1 | 1 | 100% | 5 | 20%
I'm totally blocked on the jointure part of my request. Somebody can help me ?
Without any joins - just using UNPIVOT and PIVOT:
Oracle Setup:
CREATE TABLE DICO ( "order", couple, first, second ) AS
SELECT 1, 'A-B', 'A', 'B' FROM DUAL UNION ALL
SELECT 2, 'A-D', 'A', 'D' FROM DUAL UNION ALL
SELECT 3, 'A-C', 'A', 'C' FROM DUAL UNION ALL
SELECT 4, 'A-B', 'A', 'B' FROM DUAL UNION ALL
SELECT 5, 'Y-Z', 'Y', 'Z' FROM DUAL UNION ALL
SELECT 6, 'W-A', 'W', 'A' FROM DUAL;
Query:
SELECT "order",
"count",
"1stElem_TOTAL" AS Total1stElem,
100*"count"/"1stElem_TOTAL" AS "%1stElem",
"2ndElem_TOTAL" AS Total2ndElem,
100*"count"/"2ndElem_TOTAL" AS "%2ndElem"
FROM (
SELECT couple AS "order",
key,
COUNT(*) OVER ( PARTITION BY COUPLE )/2 AS "count",
COUNT(*) OVER ( PARTITION BY VALUE ) AS num_value
FROM DICO
UNPIVOT ( Value FOR Key IN ( first AS 1, second AS 2 ) )
)
PIVOT ( MAX( NUM_VALUE ) AS Total FOR key IN ( 1 AS "1stElem", 2 AS "2ndElem" ) );
Results:
order count TOTAL1STELEM %1stElem TOTAL2NDELEM %2ndElem
----- ----- ------------ -------- ------------ --------
A-D 1 5 20 1 100
A-B 2 5 40 2 100
A-C 1 5 20 1 100
Y-Z 1 1 100 1 100
W-A 1 1 100 5 20
i want Group by by Max(Datetime) each record. but i query have dupplicatate record. i want don't duplicate record.
SQL:
select a.pmn_code,
a.ref_period,
a.SERVICE_TYPE,
min(a.status) keep (dense_rank last order by a.updated_dtm) as status,
max(a.updated_dtm) as updated_dtm
from tempChkStatus a
group by a.pmn_code, a.ref_period, a.SERVICE_TYPE
Data Table tempChkStatus:
PMN_CODE | REF_PERIOD | SERVICE_TYPE | STATUS | UPDATED_DTM
A | 01/2016 | OI | I | 19/08/2016 10:54:44
A | 01/2016 | OP | N | 06/06/2017 15:09:55
A | 02/2016 | OT | I | 31/08/2016 08:37:45
A | 02/2016 | OT | N | 12/10/2016 11:13:56
A | 04/2016 | OI | I | 19/08/2016 10:54:44
A | 04/2016 | OP | N | 06/06/2017 15:09:55
Result SQL:
PMN_CODE | REF_PERIOD | SERVICE_TYPE | STATUS | UPDATED_DTM
A | 01/2016 | OI | I | 19/08/2016 10:54:44
A | 01/2016 | OP | N | 06/06/2017 15:09:55
A | 02/2016 | OT | N | 12/10/2016 11:13:56
A | 04/2016 | OI | I | 19/08/2016 10:54:44
A | 04/2016 | OP | N | 06/06/2017 15:09:55
But I want Result:
PMN_CODE | REF_PERIOD | SERVICE_TYPE | STATUS | UPDATED_DTM
A | 01/2016 | OP | N | 06/06/2017 15:09:55
A | 02/2016 | OT | N | 12/10/2016 11:13:56
A | 04/2016 | OP | N | 06/06/2017 15:09:55
Help me please. Thanks advance ;)
with tempChkStatus (
PMN_CODE, REF_PERIOD , SERVICE_TYPE , STATUS , UPDATED_DTM) as
(
select 'A', '01/2016' ,'OI', 'I', to_date('19/08/2016 10:54:44', 'dd/mm/yyyy hh24:mi:ss') from dual union all
select 'A', '01/2016' ,'OP', 'N', to_date('06/06/2017 15:09:55', 'dd/mm/yyyy hh24:mi:ss') from dual union all
select 'A', '02/2016' ,'OT', 'I', to_date('31/08/2016 08:37:45', 'dd/mm/yyyy hh24:mi:ss') from dual union all
select 'A', '02/2016' ,'OT', 'N', to_date('12/10/2016 11:13:56', 'dd/mm/yyyy hh24:mi:ss') from dual union all
select 'A', '04/2016' ,'OI', 'I', to_date('19/08/2016 10:54:44', 'dd/mm/yyyy hh24:mi:ss') from dual union all
select 'A', '04/2016' ,'OP', 'N', to_date('06/06/2017 15:09:55', 'dd/mm/yyyy hh24:mi:ss') from dual
)
select * from (
select e.*, max(updated_dtm) over (partition by ref_period) md from tempchkstatus e
)
where updated_dtm = md
;
You just need to remove SERVICE_TYPE from the GROUP BY:
select s.pmn_code, s.ref_period,
min(s.SERVICE_TYPE) as service_type,
min(s.status) keep (dense_rank last order by s.updated_dtm) as status,
max(s.updated_dtm) as updated_dtm
from tempChkStatus s
group by s.pmn_code, s.ref_period;
The GROUP BY expressions define the rows returns by an aggregation query.
This version uses MIN() on SERVICE_TYPE. It is not clear what logic you want for the result set.
I have created these sample tables to create a json tree structure so that i can use jqtree to create a tree layout.
I want my json to be in the format
[
{"id":1, "parentid": 0, "name": "Carnivores"},
{"id":2, "parentid": 0, "name": "Herbivores"},
{"id":3, "parentid": 1, "name": "Dogs"},
{"id":4, "parentid": 3, "name": "Labradors"},
{"id":5, "parentid": 3, "name": "Pugs"},
{"id":6, "parentid": 3, "name": "Terriers"}
]
The tables are as follows.
| catg_id | catg_name |
| —————- |————————- |
| 1 | Carnivores |
| 2 | Herbivores |
| animal_catg_id | animal_catg_name | catg_id |
| —————- |————————- |————————- |
| 1 | Dogs | 1 |
| 2 | Cats | 1 |
| 3 | Cows | 2 |
| 4 | Buffalo | 2 |
| animal_id | animal_name | animal_catg_id |
| —————- |————————- | ————————- |
| 1 | labs | 1 |
| 2 | pugs | 1 |
| 3 | terriers | 1 |
| 4 | german | 1 |
| 5 | lion | 2 |
| 6 | tiger | 2 |
I am assuming it would be hierarchical query, i have never written one before, i need some help with that.
I don't know where to start and how to start it.
EDIT
One of the comments in the answers is that the schema design is not clear.
What changes should I do to make to get the data in the json format, so that it maintains the hierarchy
EDIT2
My current query returns this table
Carnivores | Dogs | labs
Carnivores | Dogs | pugs
Carnivores | Dogs | terriers
.......
The JSON you are proposing appears to have no correlation between the IDs you are assigning and the IDs in the tables this will make it difficult to connect anything from the client-side back to the database.
You would be better re-organising your tables so that you can put everything into a single hierarchical structure. Something like a Linnaean Taxonomy:
SQL Fiddle
Oracle 11g R2 Schema Setup:
CREATE TABLE Taxonomies ( ID, PARENT_ID, Category, Taxonomy, Common_Name ) AS
SELECT 1, CAST(NULL AS NUMBER), 'Kingdom', 'Animalia', 'Animal' FROM DUAL
UNION ALL SELECT 2, 1, 'Phylum', 'Chordata', 'Chordate' FROM DUAL
UNION ALL SELECT 3, 2, 'Class', 'Mammalia', 'Mammal' FROM DUAL
UNION ALL SELECT 4, 3, 'Order', 'Carnivora', 'Carnivore' FROM DUAL
UNION ALL SELECT 5, 4, 'Family', 'Felidae', 'Feline' FROM DUAL
UNION ALL SELECT 6, 5, 'Genus', 'Panthera', 'Tiger' FROM DUAL
UNION ALL SELECT 7, 5, 'Genus', 'Felis', 'Cat' FROM DUAL
UNION ALL SELECT 8, 5, 'Genus', 'Lynx', 'Lynx' FROM DUAL
UNION ALL SELECT 9, 4, 'Family', 'Canidae', 'Canid' FROM DUAL
UNION ALL SELECT 10, 9, 'Genus', 'Canis', 'Canine' FROM DUAL
UNION ALL SELECT 11, 10, 'Species', 'Canis Lupus', 'Gray Wolf' FROM DUAL
UNION ALL SELECT 12, 11, 'Sub-Species', 'Canis Lupus Familiaris', 'Domestic Dog' FROM DUAL
UNION ALL SELECT 13, 12, 'Breed', NULL, 'Pug' FROM DUAL
UNION ALL SELECT 14, 12, 'Breed', NULL, 'German Shepherd' FROM DUAL
UNION ALL SELECT 15, 12, 'Breed', NULL, 'Labradors' FROM DUAL
UNION ALL SELECT 16, 7, 'Species', 'Felis Catus', 'Domestic Cat' FROM DUAL
UNION ALL SELECT 17, 8, 'Species', 'Lynx Lynx', 'Eurasian Lynx' FROM DUAL
UNION ALL SELECT 18, 8, 'Species', 'Lynx Rufus', 'Bobcat' FROM DUAL;
Then you can extract the data relatively simply:
Query 1 - Get everything taxonomically related to "Cat":
SELECT *
FROM (
SELECT *
FROM Taxonomies
START WITH Common_Name = 'Cat'
CONNECT BY PRIOR PARENT_ID = ID
ORDER BY LEVEL DESC
)
UNION
SELECT *
FROM (
SELECT *
FROM Taxonomies
START WITH Common_Name = 'Cat'
CONNECT BY PRIOR ID = PARENT_ID
ORDER SIBLINGS BY Common_Name
)
Results:
| ID | PARENT_ID | CATEGORY | TAXONOMY | COMMON_NAME |
|----|-----------|----------|-------------|--------------|
| 1 | (null) | Kingdom | Animalia | Animal |
| 2 | 1 | Phylum | Chordata | Chordate |
| 3 | 2 | Class | Mammalia | Mammal |
| 4 | 3 | Order | Carnivora | Carnivore |
| 5 | 4 | Family | Felidae | Feline |
| 7 | 5 | Genus | Felis | Cat |
| 16 | 7 | Species | Felis Catus | Domestic Cat |
Query 2 - Get everything taxonomically related to "Canine":
SELECT *
FROM (
SELECT *
FROM Taxonomies
START WITH Common_Name = 'Canine'
CONNECT BY PRIOR PARENT_ID = ID
ORDER BY LEVEL DESC
)
UNION
SELECT *
FROM (
SELECT *
FROM Taxonomies
START WITH Common_Name = 'Canine'
CONNECT BY PRIOR ID = PARENT_ID
ORDER SIBLINGS BY Common_Name
)
Results:
| ID | PARENT_ID | CATEGORY | TAXONOMY | COMMON_NAME |
|----|-----------|-------------|------------------------|-----------------|
| 1 | (null) | Kingdom | Animalia | Animal |
| 2 | 1 | Phylum | Chordata | Chordate |
| 3 | 2 | Class | Mammalia | Mammal |
| 4 | 3 | Order | Carnivora | Carnivore |
| 9 | 4 | Family | Canidae | Canid |
| 10 | 9 | Genus | Canis | Canine |
| 11 | 10 | Species | Canis Lupus | Gray Wolf |
| 12 | 11 | Sub-Species | Canis Lupus Familiaris | Domestic Dog |
| 13 | 12 | Breed | (null) | Pug |
| 14 | 12 | Breed | (null) | German Shepherd |
| 15 | 12 | Breed | (null) | Labradors |
Here's an example of a hierarchical query from the Oracle documentation:
SELECT last_name, employee_id, manager_id, LEVEL
FROM employees
START WITH employee_id = 100
CONNECT BY PRIOR employee_id = manager_id
ORDER SIBLINGS BY last_name;
http://docs.oracle.com/cd/B19306_01/server.102/b14200/queries003.htm
Something like this in your case but your schema design isn't clear
SELECT animal_name, level
FROM animals
START WITH parentid is null
CONNECT BY PRIOR id = parentid;
i am novice at SQL and have problems hope you can help me :
ORACLE 10g
table ACCOUNT
+----------+----------+
| ACCOUNTID| LBKEY |
+----------+----------+
| ... | ... |
| 254 | value254 |
| ... | ... |
| 401 | value401 |
| ... | ... |
| 405 | value405 |
+----------+----------+
cross reference table
+----------+----------+----------+--------+
| IDTABLE2 | ACCOUNTID| OIDID | VALUE |
+----------+----------+----------+--------+
| ... | ... | ... | ... |
| 475 | 401 | 4 | 40000 |
| 476 | 405 | 4 | 35000 |
| ...| ... | ... | ... |
| 3000 | 254 | 5 | PARIS |
| 3001 | 401 | 5 | LONDON |
| 3002 | 405 | 5 | SYDNEY |
| ...| ... | ... | ... |
+----------+----------+----------+--------+
table OID
+----------+-------------+-------------+
| OIDID | OID | DESCRIPTION |
+----------+-------------+-------------+
| 1 | x | x |
| 2 | x | x |
| 3 | x | x |
| 4 | 1.3.6.1.4.1 | Post Code |
| 5 | 1.3.6.1.4.2 | City |
| 6 | x | x |
| 7 | x | x |
| 8 | x | x |
| 9 | x | x |
| 10 | x | x |
+----------+-------------+-------------+
Expected result
Constraint : all the ACCOUNT (LBKEY) who has one postal code(OID 4) or city code(OID 5) in the cross reference table
+----------+-------------+-------------+
| LBKEY | POST CODE | CITY |
+----------+-------------+-------------+
| value254 | null | PARIS |
| value401 | 40000 | LONDON |
| value405 | 35000 | SYDNEY |
+----------+-------------+-------------+
Three different ways of doing it:
SQL Fiddle
Oracle 11g R2 Schema Setup:
CREATE TABLE ACCOUNT ( ACCOUNTID, LBKEY ) AS
SELECT 254, 'value254' FROM DUAL
UNION ALL SELECT 401, 'value401' FROM DUAL
UNION ALL SELECT 405, 'value405' FROM DUAL
UNION ALL SELECT 406, 'value406' FROM DUAL;
CREATE TABLE CrossReference ( IDTABLE2, ACCOUNTID, OIDID, VALUE ) AS
SELECT 475, 401, 4, '40000' FROM DUAL
UNION ALL SELECT 476, 405, 4, '35000' FROM DUAL
UNION ALL SELECT 3000, 254, 5, 'PARIS' FROM DUAL
UNION ALL SELECT 3001, 401, 5, 'LONDON' FROM DUAL
UNION ALL SELECT 3002, 405, 5, 'SYDNEY' FROM DUAL
UNION ALL SELECT 4000, 406, 6, 'x' FROM DUAL;
CREATE TABLE OID (OIDID, OID, DESCRIPTION ) AS
SELECT 1, 'x', 'x' FROM DUAL
UNION ALL SELECT 2, 'x', 'x' FROM DUAL
UNION ALL SELECT 3, 'x', 'x' FROM DUAL
UNION ALL SELECT 4, '1.3.6.1.4.1', 'Post Code' FROM DUAL
UNION ALL SELECT 5, '1.3.6.1.4.2', 'City' FROM DUAL
UNION ALL SELECT 6, 'x', 'x' FROM DUAL
UNION ALL SELECT 7, 'x', 'x' FROM DUAL
UNION ALL SELECT 8, 'x', 'x' FROM DUAL
UNION ALL SELECT 9, 'x', 'x' FROM DUAL
UNION ALL SELECT 10, 'x', 'x' FROM DUAL;
Query 1:
SELECT LBKEY,
MAX( CASE OIDID WHEN 4 THEN VALUE END ) AS "Post Code",
MAX( CASE OIDID WHEN 5 THEN VALUE END ) AS "City"
FROM ACCOUNT a
INNER JOIN
CrossReference c
ON ( a.ACCOUNTID = c.ACCOUNTID )
WHERE c.OIDID IN ( 4, 5 )
GROUP BY LBKEY
Results:
| LBKEY | POST CODE | CITY |
|----------|-----------|--------|
| value254 | (null) | PARIS |
| value405 | 35000 | SYDNEY |
| value401 | 40000 | LONDON |
Query 2:
WITH data AS (
SELECT LBKEY,
( SELECT VALUE
FROM CrossReference c
WHERE c.ACCOUNTID = a.ACCOUNTID
AND c.OIDID = 4 ) AS "Post Code",
( SELECT VALUE
FROM CrossReference c
WHERE c.ACCOUNTID = a.ACCOUNTID
AND c.OIDID = 5 ) AS "City"
FROM ACCOUNT a
)
SELECT *
FROM data
WHERE "Post Code" IS NOT NULL
OR "City" IS NOT NULL
Results:
| LBKEY | POST CODE | CITY |
|----------|-----------|--------|
| value254 | (null) | PARIS |
| value401 | 40000 | LONDON |
| value405 | 35000 | SYDNEY |
Query 3:
SELECT LBKEY,
c1.VALUE AS "Post Code",
c2.VALUE AS City
FROM ACCOUNT a
LEFT OUTER JOIN
( SELECT ACCOUNTID, VALUE FROM CrossReference WHERE OIDID = 4 ) c1
ON ( c1.ACCOUNTID = a.ACCOUNTID )
LEFT OUTER JOIN
( SELECT ACCOUNTID, VALUE FROM CrossReference WHERE OIDID = 5 ) c2
ON ( c2.ACCOUNTID = a.ACCOUNTID )
WHERE c1.VALUE IS NOT NULL
OR c2.VALUE IS NOT NULL
Results:
| LBKEY | POST CODE | CITY |
|----------|-----------|--------|
| value254 | (null) | PARIS |
| value401 | 40000 | LONDON |
| value405 | 35000 | SYDNEY |
I think this could work for you:
select
lbkey,
cross_post.value as postcode,
cross_city.value as city
from
ACCOUNT a,
cross cross_city,
cross cross_post,
where
a.accountid=cross_city.accountid(+) and
a.accountid=cross_post.accountid(+) and
nvl(cross_city.oidid,5)=5 and
nvl(cross_post.oidid,4)=4 and
(cross_city.oidid is not null or cross_post.oidid is not null)