在同一 SQL 查询中同时使用 WHERE、CASE、AND、LIKE
Using WHERE, CASE, AND, LIKE together in the same SQL query
我无法想出执行以下操作的正确查询:假设我们以某种方式从用户那里获取两列值的输入,datestamp
和 brand
(会发生什么是 Looker UI 将其提供给查询)。为简单起见,假设我们的模式包括两列,我只想取回它们,所以:
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
和本例中出现的其他关键字的位置。
这可能是您的查询:
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 = '<>';
但是为此你每次都必须通过 x。
今天通过 0
昨天通过 1
最后 'x' 通过 'x'
在 Looker 中,我认为这一切都可以通过使用 templated filters 而不是像现在这样的参数来相当简单地完成。
基本上,模板化过滤器会自动将选择的条件应用于查询,因此您不必使用您当前拥有的 CASE 语句明确说明所有可能的用户输入形式,您可以只使用
{% condition filter_datestamp %} datestamp {% endcondition %}
这一行可以替换所有日期戳案例语句——您也可以将品牌过滤器添加到末尾,例如:
{% condition filter_datestamp %} datestamp {% endcondition %}
AND brand LIKE {% parameter filter_brand %}
那应该写出SQL想要的!如果您为 filter_brand 输入 "foo",为 filter_datestamp 输入 "yesterday",它将显示:
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 table(我猜你正在尝试做的)看起来像
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 ;;
}
}
让我知道是否扫描或是否有任何不合理的地方!此外,将来我会邀请您 post 访问我们的社区论坛 discourse.looker.com :) 我们有很多 Looker 专家,他们很乐意回答这样的问题。
我无法想出执行以下操作的正确查询:假设我们以某种方式从用户那里获取两列值的输入,datestamp
和 brand
(会发生什么是 Looker UI 将其提供给查询)。为简单起见,假设我们的模式包括两列,我只想取回它们,所以:
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
和本例中出现的其他关键字的位置。
这可能是您的查询:
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 = '<>';
但是为此你每次都必须通过 x。 今天通过 0 昨天通过 1 最后 'x' 通过 'x'
在 Looker 中,我认为这一切都可以通过使用 templated filters 而不是像现在这样的参数来相当简单地完成。
基本上,模板化过滤器会自动将选择的条件应用于查询,因此您不必使用您当前拥有的 CASE 语句明确说明所有可能的用户输入形式,您可以只使用
{% condition filter_datestamp %} datestamp {% endcondition %}
这一行可以替换所有日期戳案例语句——您也可以将品牌过滤器添加到末尾,例如:
{% condition filter_datestamp %} datestamp {% endcondition %}
AND brand LIKE {% parameter filter_brand %}
那应该写出SQL想要的!如果您为 filter_brand 输入 "foo",为 filter_datestamp 输入 "yesterday",它将显示:
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 table(我猜你正在尝试做的)看起来像
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 ;;
}
}
让我知道是否扫描或是否有任何不合理的地方!此外,将来我会邀请您 post 访问我们的社区论坛 discourse.looker.com :) 我们有很多 Looker 专家,他们很乐意回答这样的问题。