0

一个表 Jobs 有 2 列 JobId, City 当我们保存工作时,工作位置可能是多个城市,如下所示

-----------------------------
JobId               City
-------------------------------
1                   New York
2                   New York , Ohio , Virginia
3                   New York , Virginia

我如何计算特定城市的jobid,就像我想计算纽约市的jobid 我想要的结果一样

纽约 3 俄亥俄 1 弗吉尼亚 2

4

6 回答 6

3

您的数据库设计不佳,您将遇到很多麻烦。使用当前结构,您可以使用该find_in_set函数获取计数,但您应该避免使用 .

你的桌子是

create table test
(jobid int ,city varchar(100));

insert into test values 
(1,'New York'),
(2,'New York, Ohio,Virginia'),
(3,'New York,Virginia');

现在要获得计数,您可以使用以下命令

select 
count(*) as tot from test
where 
find_in_set('Virginia',city) > 0;

正如我所提到的,这是一个糟糕的数据库设计,理想的情况是

  • 首先是一个包含工作详细信息的工作表
  • 包含所有位置的位置表
  • 最后是一个连接工作和位置的表格

所以它看起来像

create table jobs (jobid int, name varchar(100));

insert into jobs values
(1,'PHP'),(2,'Mysql'),(3,'Oracle');

create table locations (id int, name varchar(100));
insert into locations values (1,'New York'),(2,'Ohio'),(3,'Virginia');

create table job_locations (id int, jobid int, location_id int);

insert into job_locations values
(1,1,1),(2,2,1),(3,2,2),(4,2,3),(5,3,1),(6,3,3);

现在获得计数和更多操作将相当容易

select
count(j.jobid) as  tot
from jobs j 
join job_locations jl on jl.jobid = j.jobid
join locations l on l.id = jl.location_id
where
l.name = 'Virginia'

为了计算每个城市的所有工作并使用上述模式,它会非常简单

select
l.name,
count(j.jobid) as  tot
from jobs j 
join job_locations jl on jl.jobid = j.jobid
join locations l on l.id = jl.location_id
group by l.name

演示

于 2014-11-27T07:50:23.593 回答
2
SELECT 
  SUBSTRING_INDEX(SUBSTRING_INDEX(all_city, ',', num), ',', -1) AS one_city,
  COUNT(*) AS cnt
FROM (
  SELECT
    GROUP_CONCAT(city separator ',') AS all_city,
    LENGTH(GROUP_CONCAT(citySEPARATOR ',')) - LENGTH(REPLACE(GROUP_CONCAT(citySEPARATOR ','), ',', '')) + 1 AS count_city
  FROM table_name
) t
JOIN numbers n
ON n.num <= t.count_city
GROUP BY one_city
ORDER BY cnt DESC;

为了获得逗号分隔的不同值的计数,在查询上方运行但获得正确的结果,您应该使用另外一张**numbers**只有一列 num 整数类型的表并插入一些值。如果您在 GROUP_CONCAT(city separator ',') AS all_city 在这种情况下遇到错误,请设置一个全局变量“SET group_concat_max_len = 18446744073709547520;”

于 2014-12-02T11:23:02.123 回答
1
SELECT COUNT(*) AS jobs 
  FROM Jobs
 WHERE FIELD_IN_SET('New York') > 0
;

不过,您应该阅读有关数据库规范化的信息。在数据库表中使用逗号分隔的值列表总是有“气味”,例如,您只能在此处检查特定的城市名称,并且不能轻松地为工作表中引用的所有城市创建工作计数列表一口气...

请参阅例如http://en.wikipedia.org/wiki/Database_normalization开始...

于 2014-11-27T07:53:11.010 回答
0

使JobIdCity列作为连接的主键。这将使您的生活更轻松。不要插入以逗号分隔的多个城市。

-------------------------------------------------
JobId               City         // Other columns
-------------------------------------------------
1                   New York
2                   New York
2                   Ohio
2                   Virginia
3                   New York
3                   Virginia

现在您进行查询将是这样的

select city, count(jobid) FROM TABLE GROUP BY city  // Result will be New York 3, Ohio 1 and Virginia 2
于 2014-11-27T07:38:12.083 回答
0

如下所述设计您的表格。每行中的每个城市名称和职位 ID。

Job ID      City Name
1           New York
2           New York
1           Seattle

然后使用下面链接中提到的查询。

SQL:如何获取列中每个不同值的计数?

于 2014-11-27T07:56:21.747 回答
0

试试这个查询,

 SELECT COUNT(jobid), city FROM TABLE where city like '%newyork%';
于 2014-11-27T09:10:31.410 回答