2014-12-30 4 views
0

Я пытаюсь создать запрос, который требует соединения по подзапросу. Однако мне также нужно ограничить результаты подзапросов результатами по моему основному запросу.Обмен значениями между запросами (и подзапросами)

Я изменил свой предыдущий вопрос, чтобы показать полный «концептуальный» запрос, который я хотел бы запустить. Я знаю, что это будет чревато проблемами, но мне не хватает опыта (в настоящее время), чтобы иметь возможность модифицировать синтаксис, достаточный для выполнения этого запроса.

Пример ниже:

SELECT 
    w.timestamp, 
    c.timestamp 
FROM 
    table1 w 
FULL OUTER JOIN 
    (SELECT 
      customer_id, 
      timestamp 
     FROM 
      table1 c 
     HAVING 
      c.timestamp < w.timestamp 
     AND 
      timestamp = MAX(c.timestamp)) c 
ON 
    w.customer_id = c.customer_id 
WHERE 
    payment_type_code='WithdrawPayment' 
AND 
    w.customer_id IN 
     (SELECT 
      customer_id, 
      timestamp 
     FROM 
      table1 
     WHERE 
      c.timestamp < w.timestamp 
     AND 
      timestamp = MAX(c.timestamp) 
    ORDER BY 
      c.timestamp DESC 
     ) 
HAVING 
    (SELECT 
     COUNT(*) 
    FROM 
     table1 u 
    WHERE 
     u.timestamp > c.timestamp 
    AND 
     u.timestamp < w.timestamp) u > 0 
; 

Любая помощь будет оценена.

+0

Правила определения области применения. Просто переместите условие «c.timestamp jarlh

+0

Так что я мог бы написать: SELECT w.timestamp, c.timestamp ИЗ table1 ш полное внешнее соединение (SELECT customer_id, метку времени FROM table1 с HAVING метку времени = MAX (c.timestamp)) c ВКЛ w.customer_id Nic2352

+0

Не уверен, что это сработает для меня, поскольку я пытаюсь присоединиться к client_id, но только когда c.timestamp Nic2352

ответ

0

Как уже упоминалось в комментариях, ваш запрос полностью испорчен: вы не можете одновременно получать как агрегированные, так и подробные данные, и вы не можете соотнести с запросом в производной таблице.

Но вы, кажется, искать максимальную отметку времени в table2 до одного таблицы1, и это может быть выражено следующим образом:

SELECT 
    w.timestamp, 
    c.timestamp 
FROM 
    table1 w 
LEFT JOIN 
    table1 c 
ON 
    w.customer_id = c.customer_id -- join on customer_id 
AND c.timestamp < w.timestamp  -- using only earlier timestamps 
WHERE 
    action_type ='type1' 
QUALIYF 
    RANK() 
    OVER (PARTITION BY w.customer_id -- assuming there's only one row per customer in w 
      ORDER BY c.timestamp DESC) = 1 -- find the maximum timestamp 
+0

Я изменил свой вопрос в вопросе выше. Я знаю, что все еще будет чревато проблемами, но, как я уже упоминал выше, у меня нет опыта или понимания, чтобы иметь возможность его достаточно модифицировать. – Nic2352

+0

Я не понимаю, чего вы пытаетесь достичь. Вы лучше объясните свои правила подробно и добавьте DDL и образцы данных. Является ли 'table1' фактически всегда одной и той же таблицей? – dnoeth

0

Ваш запрос не является действительным SQL и даже не ясно, что вы пытаясь достичь с этим. (Должен признаться, я даже не угадал цель вашего запроса.) Вы должны сказать нам, что должен делать запрос, а не просить нас указать на ваши синтаксические ошибки.

Во всяком случае, давайте начнем с производной таблицы:

SELECT customer_id, timestamp 
FROM table1 c 
HAVING c.timestamp < w.timestamp 
AND timestamp = MAX(c.timestamp) 

Вы выбираете TABLE1 записи (ограниченный столбцам customer_id и метки времени, чтобы быть точным). Вы выбираете все строки (нет предложения WHERE). Тогда есть предложение HAVING. Это недействительно здесь. Предложение HAVING работает после агрегирования значений, например. если вы выбрали MIN (customer_id) и MAX (временную метку) как одну запись или группу (с GROUP BY). Как и в случае с вашим предложением HAVING, нет никакого смысла, и я действительно задаюсь вопросом, как вы получили идею использовать его вообще.

Затем в разделе HAVING вы сравниваете отметку времени с MAX (отметка времени). Вы не можете сделать это. Есть время до агрегации, когда вы можете посмотреть, например, запись и столбец timestamp. Затем есть время после агрегации, когда вы можете посмотреть MAX (временная метка). Вы не видите их одновременно. Для этого вам нужно будет выбрать одну и ту же таблицу дважды, один раз, чтобы посмотреть на отдельные записи, один раз, чтобы посмотреть на агрегацию. Как и в:

SELECT customer_id, timestamp 
FROM table1 c 
WHERE timestamp = (select MAX(timestamp) from table1) 

Здесь я проверяю для каждой записи, равен ли его временная метка максимальной метки времени для таблицы и сохранить только те записи.

Кроме того, вы получаете доступ к w.timestamp, который не отображается здесь. Вы можете сравнить только временную метку вне запроса производной таблицы:

FROM table1 w 
FULL OUTER JOIN 
(
    SELECT customer_id, timestamp 
    FROM table1 
    WHERE timestamp = (select MAX(timestamp) from table1) 
) c ON c.timestamp = w.timestamp 

Наконец-то вы делаете полное внешнее соединение. Зачем? X FULL OUTER JOIN Y хранит записи X, которые недоступны в Y и наоборот. Вы, однако, выбираете FROM table1 w, поэтому вы получаете все записи из таблицы1 и присоединяетесь к подмножеству таблицы1 (ваш производный запрос таблицы). Таким образом, не может быть записей из производной таблицы, которые не соответствуют таблице 1. Следовательно, внешнее соединение полное не имеет никакого смысла. Затем в предложении WHERE вашего запроса вы запрашиваете определенный w.customer_id. Если внешнее соединение будет работать, вы должны составить записи, где w.customer_id - null. Предложение WHERE приведет к их устранению. Другая причина, почему ваше полное внешнее соединение не имеет смысла.

Что еще? Ну, вы спрашиваете w.customer_id IN (SELECT customer_id, timestamp FROM ...). Это синтаксически неправильно. Единственное значение w.customer_id никогда не может совпадать с парой значений customer_id, timestamp. Вместо этого вы можете задать w.customer_id IN (SELECT customer_id FROM ...).

Затем в вашем основном запросе вы используете HAVING, хотя агрегации не производится.

Я думаю, было бы хорошо, если бы вы практиковали очень простые запросы. Запрос с WHERE. Запрос с агрегацией, скажем, MAX. Запрос с агрегацией на группу (т. Е. С использованием GROUP BY). Запрос с агрегацией и предложение HAVING. Запрос с предложением WHERE и a HAVING ...

Что касается вашего запроса здесь: Возможно, то, что я сказал выше, поможет вам построить его шаг за шагом. Если нет, вернитесь и сообщите нам, что должен делать ваш запрос, и мы покажем вам, как это сделать.

Смежные вопросы