简体   繁体   English

SQL查询穷尽基于单一关系的多对多关系?

[英]SQL query exhausting many-to-many relationship based on single relationship?

I have a database containing the two tables 'businesses' and 'cities', as well as a third many-to-many relationship table called 'associations' with only two fields in addition to its rowid: 'business_id' and 'city_id'. 我有一个数据库,其中包含两个表“ businesss”和“ citys”,以及第三个名为“ associations”的多对多关系表,除了其rowid之外,仅具有两个字段:“ business_id”和“ city_id”。 A business can cover several cities, and a city can be covered by several businesses. 一个企业可以覆盖多个城市,一个城市可以被多个企业覆盖。

Now I want to list each business together with the cities it is associated with. 现在,我想列出每个业务以及与之关联的城市。 So I do this: 所以我这样做:

SELECT
  businesses.rowid,
  businesses.name,
  GROUP_CONCAT(cities.name, ', ') as citylist
FROM businesses
JOIN associations ON businesses.rowid = associations.business_id
JOIN cities ON cities.rowid = associations.city_id
GROUP BY businesses.rowid

And this works perfectly. 这完美地工作。 But what I want to do in practice, is to only list the businesses – in exactly the same way – that are associated to a given city. 但是我想在实践中要做的是,仅以完全相同的方式列出与给定城市相关的企业。 But I haven't found a way to this that will not make GROUP_CONCAT(cities.name, ', ') return only the given city, instead of all cities the business is associated with. 但是我还没有找到一种方法,该方法不会使GROUP_CONCAT(cities.name, ', ')只返回给定的城市,而不返回与业务相关的所有城市。

As a random example, if given the city "New York", I would want a result like this: 作为一个随机的例子,如果给定城市“ New York”,我想要这样的结果:

0: [rowid] = 42
   [name] = Generic Business
   [citylist] = New York, Jamestown, Albany
1: [rowid] = 31
   [name] = Arbitrary Ltd.
   [citylist] = Fulton, New York, Lockport

If it matters for the solution, I'm currently using SQLite 3, but I'm not completely opposed to changing if necessary. 如果对解决方案很重要,那么我目前正在使用SQLite 3,但我并不完全反对在必要时进行更改。

Use a having clause; 使用having子句;

SELECT b.rowid, b.name,
       GROUP_CONCAT(c.name, ', ') as citylist
FROM businesses b JOIN
     associations a
     ON b.rowid = a.business_id JOIN
     cities c
     ON c.rowid = a.city_id
GROUP BY b.rowid, b.name
HAVING SUM(CASE WHEN c.name = 'New York' THEN 1 ELSE 0 END) > 0;

Notes: 笔记:

  • Table aliases (the a , b , and c ) make the query easier to write and to read. 表别名( abc )使查询更易于编写和阅读。
  • I prefer to put all the unaggregated columns in the SELECT in the GROUP BY for clarity purposes. 为了清楚起见,我更喜欢将所有未聚合的列放在GROUP BYSELECT中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM