找到所有孩子都具有相同价值的父母

时间:2016-02-11 09:21:36

标签: sql sql-server

我在查询此问题时遇到了困难。

假设我们有3个表格,如下所示:

company
    id int IDENTITY,
    name nvarchar(255)

location
    id int IDENTITY,
    name nvarchar(255),
    company int

address
    id int IDENTITY,
    name nvarchar(255),
    location int

请忽略此用例的键和索引。

我想返回一个公司列表,其所有子位置都有一个指定的地址,该公司所有位置的地址都相同。

示例工作数据:

select c.name, l.name, a.name
from company as c
join location as l on l.company = c.id
left join address as a on a.location = l.id



company     location          address
----------  ----------------  -----------------
3-DOM       Ankh-Morpork      Street 1
Adrenalize  Cabot Cove        Avenue 2
Adrenalize  Mayberry          Road 49
InterBlurb  Hogsmeade         NULL
InterBlurb  Kakariko Village  Alleyway 13
Octocore    Nibelheim         Blueberry Creek 2
Octocore    Mos Eisley        Blueberry Creek 2

示例结果:

company   
----------
3-DOM     
Octocore

我将如何实现这一结果?我已尝试按l.company分组并选择count(distinct a.name)和其他内容,但我似乎无法掌握它。我非常感谢您对查询的解释,我需要理解这一点。

2 个答案:

答案 0 :(得分:1)

您可以尝试按公司名称进行分组,并仅保留所有位置地址相同的公司(这是内部查询的作用):

WITH the_cte (companyName, locationName, address)
AS
(
    SELECT c.name, l.name, a.name
    FROM company AS c
    INNER JOIN location AS l
        ON l.company = c.id
    LEFT JOIN address AS a
        ON a.location = l.id
)

SELECT companyName, locationName, address
FROM the_cte
INNER JOIN
(
    SELECT companyName, COUNT(DISTINCT CASE WHEN address IS NULL THEN 0 ELSE 1 END)
    FROM the_cte
    GROUP BY companyName
    HAVING COUNT(DISTINCT CASE WHEN address IS NULL THEN 0 ELSE 1 END) = 1
) t
    ON the_cte.companyName = t.companyName

答案 1 :(得分:1)

SELECT Name 
FROM (
                SELECT        company.name
                FROM            company INNER JOIN
                                         location ON company.id = location.company LEFT OUTER JOIN
                                         address ON location.id = address.location
                GROUP BY company.name
                )sub

WHERE Name NOT IN (
                SELECT        company.name
                FROM            company INNER JOIN
                                         location ON company.id = location.company LEFT OUTER JOIN
                                         address ON location.id = address.location
                WHERE        (address.location IS NULL)
                GROUP BY company.name

                UNION

                SELECT        company.name
                FROM            location INNER JOIN
                                         address ON location.id = address.location INNER JOIN
                                         company ON location.company = company.id
                GROUP BY company.name
                HAVING        (COUNT(DISTINCT address.name) >1 )

                )
  1. 使用外部选择查询,我们结合了3个sql查询
  2. 第一个查询获取所有公司名称
  3. 第二个查询获取没有地址的公司
  4. 第三个查询获得具有多个不同位置的公司