简体   繁体   中英

outer query column in inner query case expression

I am trying to write below query in vertica

`SELECT a.* 
FROM   a 
WHERE  a.country="India" 
AND    a.language ="Hindi" 
AND   ( CASE WHEN (a.spoken = true 
             AND exist ( select 1 
                         FROM   b 
                         WHERE  b.country=a.country 
                          AND    b.language=a.language 
                          AND   ( CASE WHEN (a.population <b.population
                                    AND    a.statsyear > b.statsyear)) 
                                      THEN true //pick recent stats
                                    WHEN (a.population > b.population) 
                                      THEN true 
                                          ELSE false 
                                   END)) THEN true 
                     WHEN (a.written = true ) THEN
                       true   
                     ELSE false 
              END)`

it is not working, because we can't reference "a.population" outer query field in case expression of innerquery. I tried rewriting it wil OR caluse Vertica is not allowing it.

How can I re-write this

I created below tables in MySQL local box

 Example of Tables and Results
    CREATE TABLE tableA
(
   id          INT,
   country     VARCHAR(20),
   language    VARCHAR(20),
   spoken      INT,
   written     INT,
   population  INT,
   stats       INT
)
insert into tableA values(1,'India','Hindi',1,0,9,2010)
insert into tableA values(2,'India','Hindi',1,0,11,2011)
insert into tableA values(3,'India','Hindi',1,0,10,2012)
insert into tableA values(4,'India','Hindi',0,1,10,2013)
insert into tableA values(5,'India','Hindi',1,1,10,2012)
insert into tableA values(6,'India','English',1,1,10,2012)
CREATE TABLE tableB
(
   id          INT,
   country     VARCHAR(20),
   language    VARCHAR(20),
   population  INT,
   stats       INT
)
insert into TableB values(1,'India','Hindi',10,2009)
insert into TableB values(2,'India','Hindi',10,2011)
insert into TableB values(3,'India','Hindi',10,2012)

Rewrote the query slightly in different way

select distinct a.id
from (
SELECT a.* 
FROM   TableA a 
WHERE  a.country="India" 
AND    a.language ="Hindi" ) a, TableB   b
WHere ( CASE WHEN a.written=1 THEN
               TRUE
            WHEN ( (a.spoken = 1) AND (a.country=b.country) AND (a.language=b.language)) THEN
                 (case WHEN ((a.population < b.population) AND (a.stats > b.stats)) THEN
                        TRUE
                  WHEN (a.population > b.population) THEN
                       TRUE
                  ELSE
                     FALSE              
                END)
             ELSE
               FALSE
             END)
 got below results
 1,2,4,5

This is what I need, now could you please help me in writing it more efficient manner

Boolean logic equivalent:

SELECT DISTINCT a.* 
FROM   TableA a 
left join TableB b on a.country=b.country AND a.language=b.language
WHERE  a.country='India' 
AND    a.language ='Hindi'
AND (
        a.written=1
    OR
       (a.spoken = 1 AND a.population < b.population AND a.stats > b.stats)
    OR
       a.population > b.population
    )
;

Result:

+----+---------+----------+--------+---------+------------+-------+
| id | country | language | spoken | written | population | stats |
+----+---------+----------+--------+---------+------------+-------+
|  1 | India   | Hindi    |      1 |       0 |          9 |  2010 |
|  2 | India   | Hindi    |      1 |       0 |         11 |  2011 |
|  4 | India   | Hindi    |      0 |       1 |         10 |  2013 |
|  5 | India   | Hindi    |      1 |       1 |         10 |  2012 |
+----+---------+----------+--------+---------+------------+-------+

Demo

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