Использование WHERE, CASE, AND, LIKE вместе в одном SQL-запросе
У меня возникают проблемы с правильным запросом, который выполняет следующее: допустим, мы каким-то образом принимаем данные от пользователя для значения двух столбцов, datestamp
а также brand
(что происходит, пользовательский интерфейс Looker направляет это в запрос). Для простоты предположим, что наша схема включает в себя оба столбца, и я хочу только вернуть их, поэтому:
SELECT brand, datestamp
FROM my_table
WHERE
Я не уверен, как я должен написать остальное. Вот что нужно:
Пользователь сможет печатать
yesterday
,today
,last x days
для некоторыхx
или строка как20181001
и правильная дата передается в запрос.Пользователь сможет указать, что
brand
должно быть равно, и это передается в запрос.( CASE WHEN position(' TO ' IN UPPER({% parameter filter_datestamp %})) > 0 THEN datestamp >= SUBSTR({% parameter filter_datestamp %}, 0, strpos(UPPER({% parameter filter_datestamp %}), ' TO ') - 1) AND datestamp <= SUBSTR({% parameter filter_datestamp %}, strpos(UPPER({% parameter filter_datestamp %}), ' TO ') + 4) AND brand LIKE {% parameter filter_brand %} WHEN filter_datestamp = 'today' THEN datestamp = date_format(CURRENT_DATE,'yyyyMMdd') AND brand LIKE {% parameter filter_brand %} WHEN datestamp = 'yesterday' THEN datestamp = date_format(DATE_ADD('day', -1, CURRENT_DATE),'%Y%m%d') AND brand LIKE {% parameter filter_brand %} WHEN datestamp LIKE 'last % days' THEN datestamp >= date_format(DATE_ADD('day', -CAST(split({% parameter filter_datestamp %}, ' ')[2] AS INT), CURRENT_DATE),'%Y%m%d') AND brand LIKE {% parameter filter_brand %} ELSE datestamp LIKE {% parameter filter_datestamp %} AND brand LIKE {% parameter filter_brand %} END )
Если запрос работает, результатом должно быть количество строк с brand
а также datestamp
равный тому, что хочет пользователь. Все строки будут идентичны (я действительно хочу что-то еще, но думаю, что смогу сделать это, если CASE
решено).
Пожалуйста, напишите полный запрос для меня. Я не уверен где WHERE
идет в отношении CASE
, WHEN
, AND
и другие ключевые слова, присутствующие в этом случае.
2 ответа
В Looker я думаю, что все это можно сделать довольно просто, просто используя шаблонные фильтры вместо параметров, которые вы используете сейчас.
По сути, шаблонные фильтры автоматически применяют выбранное условие к запросу, поэтому вместо того, чтобы явно учитывать все возможные формы пользовательского ввода с помощью операторов CASE, которые у вас есть в настоящее время, вы могли бы просто иметь
{% condition filter_datestamp %} datestamp {% endcondition %}
Эта одна строка может заменить все операторы регистра даты и даты. Вы также можете включить фильтр бренда, добавив его в конец, например:
{% condition filter_datestamp %} datestamp {% endcondition %}
AND brand LIKE {% parameter filter_brand %}
Это должно написать желаемый SQL! Если вы введете "foo" для filter_brand и "вчера" для filter_datestamp, он напишет:
SELECT brand, datestamp
FROM my_table
WHERE ((( datestamp ) >= ((DATE_ADD(CURDATE(),INTERVAL -1 day))) AND ( datestamp ) < ((DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -1 day),INTERVAL 1 day)))))
AND brand LIKE 'foo'
Полный LookML, чтобы иметь его как производную таблицу (как я догадался, вы пытались сделать) выглядит так
view: test {
derived_table: {
sql:
SELECT brand, datestamp
FROM my_table
WHERE {% condition filter_datestamp %} datestamp {% endcondition %}
AND brand LIKE {% parameter filter_brand %};;
}
filter: filter_datestamp {
type: date
}
filter: filter_brand {
type: string
}
dimension: brand {
type: string
sql: ${TABLE}.brand ;;
}
dimension: datestamp {
type: date
sql: ${TABLE}.datestamp ;;
}
}
Дайте мне знать, если это сканирует или есть что-то, что не имеет смысла в этом! Кроме того, в будущем я бы пригласил вас прийти на наши форумы сообщества по адресу http://discourse.looker.com/:) У нас есть много экспертов по поиску, которые с удовольствием ответят на подобные вопросы.
Это может быть ваш запрос:
SELECT brand, datestamp FROM my_table
WHERE (DATE (datestamp) = DATE (NOW ())
OR DATE (datestamp) >= DATE_SUB (DATE (NOW ()), INTERVAL 'x' DAY) DATE(NOW()))
AND brand = '<>';
но для этого тебе придется каждый раз проходить мимо. для сегодняшнего прохода 0 для вчерашнего прохода 1 для последнего прохода 'x', который 'x'