Проверка SQL-запроса - PullRequest
       0

Проверка SQL-запроса

1 голос
/ 02 ноября 2019

Я новичок в SQL и собираюсь написать запрос для идентификации пользователей, чья первая транзакция была успешной картой сверх эквивалентной стоимости 10 USD (суммы указаны в разных валютах). Это теоретическое упражнение, при котором у меня есть базы данных в Excel, но в настоящее время я не могу получить доступ к каким-либо SQL-серверам для проверки этого запроса.

Во-первых, Я определил результирующий набор следующим образом:

   SELECT t.user_id, min(t.created_date), (t.amount / fx.rate / Power (10, cd.exponent) AS amount) 
     FROM transactions AS t

Это должно привести к идентификатору пользователя, самой ранней дате транзакции и сумме транзакции в долларах США (исходная транзакция конвертируется в доллары США и конвертируется в денежную сумму из целой суммы).

Довольно комфортно с последней формулой, просто хочу убедиться, что ссылка ниже правильно возвращает fx.rate и cd.exponent, чтобы он мог действительно работать:

   JOIN fx_rates AS fx 
     ON ( fx.ccy = t.currency 
          AND fx.base_ccy = 'USD' ) 
   JOIN currency_details AS cd 
     ON cd.currency = t.currency 

Приведенное выше должно обеспечить, чтобы в столбце «сумма» были все ссылки, необходимые для расчета.

Наконец Я хочу применить набор ограничений, поэтому данные включают только заполненоплатежи по карте на сумму более 10 долларов США :

  WHERE t.type='card_payment'
    AND t.state='completed'
    AND amount>=10

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

У меня есть два вопроса:

1) Будет ли этот запрос производить список первых транзакций, которые были более 10USD? Я не хочу, чтобы он узнал, когда / если транзакция достигла этого порога. Меня интересует только первая транзакция для каждого пользователя. Если ответ «нет», лучше ли мне создавать таблицу с первыми транзакциями и фильтровать ее? Честно говоря, я думал, что это то, что я делаю здесь.

2) Допустима ли ссылка на псевдоним «количество» в запросе? Если нет, требуется ли здесь другой SELECT?

Полный запрос

      SELECT t.user_id, min(t.created_date), (t.amount / fx.rate / Power (10, cd.exponent) AS amount) 
      FROM transactions AS t
        JOIN fx_rates AS fx 
         ON ( fx.ccy = t.currency 
          AND fx.base_ccy = 'USD' ) 
        JOIN currency_details AS cd 
         ON cd.currency = t.currency
      WHERE t.type='card_payment'
        AND t.state='completed'
        AND amount>=10

------- ОБНОВЛЕНИЕ 1 -------

После многочисленных комментариев и ответов обновленный запрос выглядит следующим образом:

SELECT t.user_id, t.created_date, 
  (t.amount / fx.rate / Power(10, cd.exponent)) AS amount
FROM ( 
    SELECT *, Row_Number () OVER
  (PARTITION BY t.user_id ORDER BY t.created_date) AS RowNum 
    FROM transactions AS t)
  JOIN fx_rates fx 
    ON ( fx.ccy = t.currency
      AND fx.base_ccy = ‘USD') 
  JOIN currency_details cd 
    ON cd.currency = t.currency
WHERE RowNum = 1 
  AND t.type = ‘card_payment‘
  AND t.state = ‘completed‘
  AND (t.amount / fx.rate / Power(10, cd.exponent)) >= 10
GROUP  BY t.user_id;

Ответы [ 3 ]

0 голосов
/ 02 ноября 2019

"Будет ли этот запрос производить список первых транзакций, которые были более 10 долларов США?"
Нет. Помимо того, что написанное вами будет выдавать несколько ошибок, логика , которую вы пытаетесь здесьне будет ограничивать результаты первой транзакции, скорее всего, будет возвращена первая дата выполненного платежа по карте свыше 10 .

"Ссылка на псевдоним"сумма "разрешена в запросе?"
Нет. Но вы можете повторить ту же часть оператора выбора.

ниже все не проверено
Существует множество способоввыполнить то, что вы хотите. Один из самых простых для понимания (я думаю) - начать с запроса, который упорядочивает транзакции по дате для пользователя:

select *, row_number() over (partition by user_id order by created_date) rown
from transactions

, заключенный в указанном выше запросе, - номер строки для каждого пользователя (разделение по user_id) с самой ранней датой (по порядку от созданного_даты), являющейся строкой 1. Выходные данные этого запроса будут иметь несколько столбцов rown, равных 1. Каждая из этих строк представляет первую в истории транзакцию для этого пользователя. Вы можете бросить этот запрос в подзапрос и выбрать только те строки, где rown = 1

select *
from (
   select *, row_number() over (partition by user_id order by created_date) rown
   from transactions
) t
where t.rown=1

СЕЙЧАС вы можете добавить остальные ваши вещи (заметьте, я не знаю, что делать с вашим power()заявление)

select t.user_id, t.created_date, t.amount / fx.rate / 10.0 / cd.exponent AS amount
from (
   select *, row_number() over (partition by user_id order by created_date) rown
   from transactions
) t
inner JOIN fx_rates AS fx 
   ON fx.ccy = t.currency
   AND fx.base_ccy = 'USD'
inner JOIN currency_details AS cd ON cd.currency = t.currency
where t.rown=1
   and t.type='card_payment'
   AND t.state='completed'
   and t.amount / fx.rate / 10.0 / cd.exponent > 10.0

Возможно, вы захотите> = 10,0, если вы действительно хотите не менее $ 10.

0 голосов
/ 02 ноября 2019

Вы также можете использовать CTE (общие табличные выражения)

С User_CTE (идентификатор_пользователя, созданный_дата, сумма, RowNum) AS (ВЫБЕРИТЕ user_id, t.created_date, (t.amount / fx.rate / Power (10, cd.exponent)) AS сумма, ROW_NUMBER больше (PARTITION BY t.user_id ORDER BY t.created_date asc) AS RowNum ОТ транзакций t ПРИСОЕДИНЯЕТСЯ fx_rates fx ON (fx.ccy = t.currency AND fx.base_ccy = 'USD') ПРИСОЕДИНЯЙТЕСЬ currency_details cd ON cd.currency = t.currency WHERE
t.type = 'card_payment' AND t.state = 'complete' AND (t.amount / fx.rate / Power (10, cd.exponent))> = 10

) ВЫБЕРИТЕ user_id, созданный_датой, сумма ОТ
User_CTE ГДЕ
RowNum = 1

0 голосов
/ 02 ноября 2019

Псевдоним имени столбца amount недоступен в условии where.

Вы должны повторить код

 SELECT t.user_id, min(t.created_date), (t.amount / fx.rate / Power (10, cd.exponent) )  AS amount
  FROM transactions AS t
    JOIN fx_rates AS fx 
     ON ( fx.ccy = t.currency 
      AND fx.base_ccy = 'USD' ) 
    JOIN currency_details AS cd 
     ON cd.currency = t.currency
  WHERE t.type='card_payment'
    AND t.state='completed'
    AND (t.amount / fx.rate / Power (10, cd.exponent) )>=10

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...