1

我想计算来自同一列且具有相同 WHERE 条件的多个子字符串的出现次数。对于每个子字符串,我都有一个 UNION SELECT 语句,包括重复的 WHERE 条件。最终结果是使用 appox 进行的查询。2500行sql代码,但效果不错。

查询的简化示例:

SELECT ‘be’ AS country, count(destination) FROM demo
WHERE destination LIKE ‘%be%’ AND field_a=xzx AND field_b=bbb

UNION SELECT ‘de’ AS country, count(destination) FROM demo
WHERE destination LIKE ‘%de%’ AND field_a=xzx AND field_b=bbb

UNION SELECT ‘fr’ AS country, count(destination) FROM demo
WHERE destination LIKE ‘%fr%’ AND field_a=xzx AND field_b=bbb

UNION SELECT ‘nl’ AS country, count(destination) FROM demo
WHERE destination LIKE ‘%nl%’ AND field_a=xzx AND field_b=bbb

是否可以修改查询以使 WHERE 条件仅在查询中出现一次?

请通过此链接找到我的问题的简化示例:

https://docs.google.com/document/d/1otjZZlBy6au5E2I7T6NdSYmLayhNGWyXGxGo3gBx_-w/edit

4

3 回答 3

1

不要将逗号分隔的值存储在单个字段中。相反,使用多:多关系表并每行存储一个 (id,country) 组合。您的数据结构是 SQL 反模式,违反了所有关系数据库设计原则。

CREATE TABLE map (
  demo_id INT,
  country VARCHAR(2),
  PRIMARY KEY (demo_id, country)
)

INSERT INTO map VALUES
  (1, 'nl'), (1, 'de'), (1, 'be'), (1, 'fr'),
  (2, 'de'), (2, 'fr'), (2, 'be'),
  (3, 'fr'), (3, 'nl'),
  (4, 'nl')

然后你将有这个单一的查询......

SELECT
  map.country,
  COUNT(*)
FROM
  demo
INNER JOIN
  map
    ON map.demo_id = demo.id
WHERE
      demo.field_a = 'xzx'
  AND demo.field_b = 'bbb'
于 2012-07-06T09:26:46.850 回答
1
select a.country,count(*) from
(
select 'be' as country
union all
select 'de' as country
union all
select 'fr' as country
union all
select 'nl' as country
)a join demo d
on d.destination like '%'+a.country+'%'
AND d.field_a=xzx AND d.field_b=bbb
group by a.country

我不确定 mySQL 是否支持派生表。如果不支持,您必须创建一个包含所有不同国家/地区值的临时表,并将其替换为上述查询中的表 a

于 2012-07-06T09:36:37.810 回答
0

采用COUNT CASE WHEN ... THEN ... END

SELECT 
COUNT(CASE WHEN destination LIKE "%be%" THEN 1 ELSE NULL END) AS "BE",
COUNT(CASE WHEN destination LIKE "%fr%" THEN 1 ELSE NULL END) AS "FR",
COUNT(CASE WHEN destination LIKE "%de%" THEN 1 ELSE NULL END) AS "DE",
COUNT(CASE WHEN destination LIKE "%nl%" THEN 1 ELSE NULL END) AS "NL"
FROM demo
WHERE field_a = "xzx" AND field_b = "bbb"

但是你真的应该考虑改变你的表的结构。并不真正推荐在单个字段中使用逗号分隔值。

相反,例如,您应该在此处为每次旅行提供一个 ID(或者无论它是什么,我说旅行是因为目的地字段)。然后,为这次旅行中的每个目的地输入一个条目。使用这种结构,您会有这样的请求:

SELECT destination, COUNT(id) 
FROM demo 
WHERE field_a = "xzx" AND field_b = "bbb" 
GROUP BY destination
于 2012-07-06T09:21:24.367 回答