как использовать столбец из одного подзапроса в другой подзапрос - PullRequest
0 голосов
/ 16 октября 2019

У меня есть два подзапроса. Я хочу поместить p.price из первого подзапроса во второстепенный подзапрос (место XXX). но получите ошибку => ORA-00904: "P". "PRICE": неверный идентификатор

select 
    p.product_id,
    p.price, 
    l.delegation, 
    l.state 
from users
inner join (
    select 
        start_date,
        price,
        product_id, 
        row_number() over (partition by serial order by start_date desc ) as rn
    from prices 
) p on users.serial = p.serial 
inner join (
    select 
        sso_id , 
        delegation,
        state,
        updated_at, 
        row_number() over (partition by state order by updated_at asc) as tl  
    from payments
    where state = 'green' or (state = 'yellow' and delegation > XXX)
) l on users.sso_id= l.sso_id
where  
    p.rn = 1 
    and l.tl = 1 

Ответы [ 3 ]

1 голос
/ 16 октября 2019

Присоединитесь к таблице PAYMENTS и отфильтруйте строки, чтобы исключить недопустимые state / delegation строки, а затем сгенерируйте ROW_NUMBER и примените фильтр для поиска первой строки на раздел:

Настройка Oracle :

CREATE TABLE users ( serial, sso_id ) AS
SELECT 1, 1 FROM DUAL UNION ALL
SELECT 2, 2 FROM DUAL UNION ALL
SELECT 3, 3 FROM DUAL;

CREATE TABLE prices ( serial, start_date, price, product_id ) AS
SELECT 1, DATE '2019-01-01', 20, 1 FROM DUAL UNION ALL
SELECT 1, DATE '2019-02-01', 30, 2 FROM DUAL UNION ALL
SELECT 1, DATE '2019-03-01', 25, 3 FROM DUAL UNION ALL
SELECT 2, DATE '2019-01-01', 20, 1 FROM DUAL UNION ALL
SELECT 2, DATE '2019-02-01', 25, 2 FROM DUAL UNION ALL
SELECT 2, DATE '2019-03-01', 30, 3 FROM DUAL UNION ALL
SELECT 3, DATE '2019-01-01', 40, 3 FROM DUAL;

CREATE TABLE payments ( sso_id, delegation, state, updated_at ) AS
SELECT 1, 20, 'green',  DATE '2019-01-01' FROM DUAL UNION ALL
SELECT 1, 30, 'green',  DATE '2019-02-01' FROM DUAL UNION ALL
SELECT 1, 27, 'green',  DATE '2019-03-01' FROM DUAL UNION ALL
SELECT 1, 22, 'green',  DATE '2019-04-01' FROM DUAL UNION ALL
SELECT 1, 26, 'yellow', DATE '2019-05-01' FROM DUAL UNION ALL
SELECT 2, 31, 'yellow', DATE '2019-01-01' FROM DUAL UNION ALL
SELECT 2, 31, 'green',  DATE '2019-02-01' FROM DUAL UNION ALL
SELECT 3, 30, 'green',  DATE '2019-01-01' FROM DUAL UNION ALL
SELECT 3, 30, 'yellow', DATE '2019-01-01' FROM DUAL UNION ALL
SELECT 3, 50, 'yellow', DATE '2019-02-01' FROM DUAL;

Запрос :

SELECT product_id,
       price, 
       delegation, 
       state
FROM   (
  select p.product_id,
         p.price, 
         l.delegation, 
         l.state,
         row_number() over ( partition by l.sso_id, l.state order by l.updated_at asc) as tl  
  from   users
         inner join (
           select serial,
                  start_date,
                  price,
                  product_id, 
                  row_number() over (partition by serial order by start_date desc ) as rn
           from   prices 
         ) p
         on ( users.serial = p.serial AND p.rn = 1 )
         inner join payments l
         on ( users.sso_id = l.sso_id AND ( l.state = 'green' or (l.state = 'yellow' and l.delegation > p.price ) ) )
)
where  tl = 1

Вывод :

PRODUCT_ID | PRICE | DELEGATION | STATE 
---------: | ----: | ---------: | :-----
         3 |    25 |         20 | green 
         3 |    25 |         26 | yellow
         3 |    30 |         31 | green 
         3 |    30 |         31 | yellow
         3 |    40 |         30 | green 
         3 |    40 |         50 | yellow

дБ <> скрипка здесь

0 голосов
/ 16 октября 2019

Нам нужно присоединиться к вашей таблице users и price к вашей payment, чтобы получить соответствие p.price

SELECT p.product_id,
    p.price,
    l.delegation,
    l.state
FROM users
INNER JOIN
    (SELECT start_date,
        price,
        product_id,
        ROW_NUMBER() OVER (PARTITION BY serial ORDER BY start_date DESC) AS rn
    FROM prices) p ON users.serial = p.serial
INNER JOIN
    (SELECT y.sso_id,
        y.delegation,
        y.state,
        y.updated_at,
        ROW_NUMBER () OVER (PARTITION BY y.state ORDER BY y.updated_at ASC) AS tl
    FROM payments y
    INNER JOIN users u ON u.sso_id = y.sso_id
    INNER JOIN prices p ON p.serial = y.serial
    WHERE tl.state = 'green' OR (tl.state = 'yellow' AND tl.delegation > p.price)) l ON users.sso_id = l.sso_id
WHERE  
      AND p.rn = 1 AND l.tl = 1
0 голосов
/ 16 октября 2019

Используйте его в основном WHERE предложении

select 
    p.product_id,
    p.price, 
    l.delegation, 
    l.state 
from users
inner join (
    select 
        start_date,
        price,
        product_id, 
        row_number() over (partition by serial order by start_date desc ) as rn
    from prices 
) p on users.serial = p.serial 
inner join (
    select 
        sso_id , 
        delegation,
        state,
        updated_at, 
        row_number() over (partition by state order by updated_at asc) as tl  
    from payments
    where state = 'green' or state = 'yellow'
) l on users.sso_id= l.sso_id
where  
    p.rn = 1 
    and l.tl = 1 
    -- add following condition
and l.delegation > p.price
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...