如何使用两个属性并连接两个表来计算唯一属性值?
How can I count unique attribute values using two attributes and joining two tables?
我是 SQL 的初学者。
简化一下,我有两个table,districts
和streetdistricts
,里面包含了市区和街道的信息。每个区都有一个唯一的编号 dkey
,每条街道都有一个唯一的街道编号 stkey
(分别作为主键)。
这是一个例子:
Table districts
:
dkey
name
1
Inner City
2
Outer City
3
Outskirts
Table streetdistricts
:
stkey
dkey
113
1
126
2
148
2
148
3
152
3
154
3
我现在想做的是找出每个区有多少条街道只位于一个区内。所以这意味着我不必只删除重复项(比如此处 stkey 为 148 的街道),而是完全删除位于多个地区的街道,以便我只看到地区和每个地区的街道数量仅位于一区。
对于这个例子,这将是:
name number_of_street_in_just_this_district
Inner City 1
Outer City 1
Outskirts 2
我尝试了很多东西,但我总是卡住,主要是因为当我 SELECT
区的名称时,GROUP BY
中也需要它,如 SQL 所说,但是当我添加它时,会显示街道的总数(此处:6)或至少包括重复项的数量(此处:5),但不是 3.
的正确答案
或者我无法正确 JOIN
table 以获得我想要的输出。这是我最后一次尝试:
SELECT SUM(StreetDistricts.dkey) as d_number, StreetDistricts.stkey, COUNT(StreetDistricts.stkey) as numb
FROM StreetDistricts
INNER JOIN Districts ON Districts.dkey = StreetDistricts.dkey
GROUP BY StreetDistricts.stkey
HAVING COUNT(StreetDistricts.dkey) = 1
ORDER BY d_number DESC
这可以让我得到正确的行总和,但我无法 combine/join 它与另一个 table 一起接收唯一街道的名称和数量。
先获取只有一个区(cte1)的街道。然后只计算每个地区的那些街道。应该这样做:
WITH cte1 AS (
SELECT stkey FROM StreetDistricts GROUP BY stkey HAVING COUNT(DISTINCT dkey) = 1
)
SELECT d.name, COUNT(*) AS n
FROM StreetDistricts AS s
JOIN Districts AS d
ON s.dkey = d.dkey
AND s.stkey IN (SELECT stkey FROM cte1)
GROUP BY d.dkey
;
结果:
+------------+---+
| name | n |
+------------+---+
| Inner City | 1 |
| Outer City | 1 |
| Outskirts | 2 |
+------------+---+
注意:我使用 dkey 是 Districts 的主键这一事实来避免也必须 GROUP BY d.name。这是由功能依赖保证的。如果您的数据库不能通过约束保证这一点,只需将 d.name 添加到最终的 GROUP BY 条款中。
测试用例:
CREATE TABLE Districts (dkey int primary key, name varchar(30));
CREATE TABLE StreetDistricts (stkey int, dkey int);
INSERT INTO Districts VALUES
(1,'Inner City')
, (2,'Outer City')
, (3,'Outskirts')
;
INSERT INTO StreetDistricts VALUES
(113,1)
, (126,2)
, (148,2)
, (148,3)
, (152,3)
, (154,3)
;
我是 SQL 的初学者。
简化一下,我有两个table,districts
和streetdistricts
,里面包含了市区和街道的信息。每个区都有一个唯一的编号 dkey
,每条街道都有一个唯一的街道编号 stkey
(分别作为主键)。
这是一个例子:
Table districts
:
dkey | name |
---|---|
1 | Inner City |
2 | Outer City |
3 | Outskirts |
Table streetdistricts
:
stkey | dkey |
---|---|
113 | 1 |
126 | 2 |
148 | 2 |
148 | 3 |
152 | 3 |
154 | 3 |
我现在想做的是找出每个区有多少条街道只位于一个区内。所以这意味着我不必只删除重复项(比如此处 stkey 为 148 的街道),而是完全删除位于多个地区的街道,以便我只看到地区和每个地区的街道数量仅位于一区。
对于这个例子,这将是:
name number_of_street_in_just_this_district
Inner City 1
Outer City 1
Outskirts 2
我尝试了很多东西,但我总是卡住,主要是因为当我 SELECT
区的名称时,GROUP BY
中也需要它,如 SQL 所说,但是当我添加它时,会显示街道的总数(此处:6)或至少包括重复项的数量(此处:5),但不是 3.
或者我无法正确 JOIN
table 以获得我想要的输出。这是我最后一次尝试:
SELECT SUM(StreetDistricts.dkey) as d_number, StreetDistricts.stkey, COUNT(StreetDistricts.stkey) as numb
FROM StreetDistricts
INNER JOIN Districts ON Districts.dkey = StreetDistricts.dkey
GROUP BY StreetDistricts.stkey
HAVING COUNT(StreetDistricts.dkey) = 1
ORDER BY d_number DESC
这可以让我得到正确的行总和,但我无法 combine/join 它与另一个 table 一起接收唯一街道的名称和数量。
先获取只有一个区(cte1)的街道。然后只计算每个地区的那些街道。应该这样做:
WITH cte1 AS (
SELECT stkey FROM StreetDistricts GROUP BY stkey HAVING COUNT(DISTINCT dkey) = 1
)
SELECT d.name, COUNT(*) AS n
FROM StreetDistricts AS s
JOIN Districts AS d
ON s.dkey = d.dkey
AND s.stkey IN (SELECT stkey FROM cte1)
GROUP BY d.dkey
;
结果:
+------------+---+
| name | n |
+------------+---+
| Inner City | 1 |
| Outer City | 1 |
| Outskirts | 2 |
+------------+---+
注意:我使用 dkey 是 Districts 的主键这一事实来避免也必须 GROUP BY d.name。这是由功能依赖保证的。如果您的数据库不能通过约束保证这一点,只需将 d.name 添加到最终的 GROUP BY 条款中。
测试用例:
CREATE TABLE Districts (dkey int primary key, name varchar(30));
CREATE TABLE StreetDistricts (stkey int, dkey int);
INSERT INTO Districts VALUES
(1,'Inner City')
, (2,'Outer City')
, (3,'Outskirts')
;
INSERT INTO StreetDistricts VALUES
(113,1)
, (126,2)
, (148,2)
, (148,3)
, (152,3)
, (154,3)
;