左连接 count() 并在 table 内单独显示匹配项
Left join with count() and show matches separately within table
我数了不同日期和地区的鸟类。有些鸟有一个跟踪 ID。
这给了我一个 table 和这个 header。 t1
:
SPECIES | AGE | BIRD_TRACKING_ID | AREA | DATE_1
------------------------------------------------
| | | |
然后我们观察了鸟类,并记录了它们降落的树木。每棵树都有一个唯一的 ID。一只鸟本可以拜访过 none,一只鸟或几棵树。这给了我 table t2
这个 header:
TREE |DESCR |TREE_ID |BIRD_ID
------------------------------
| | |
CREATE TABLE birds (
SPECIES varchar(255),
AGE varchar(255),
BIRD_TRACKING_ID varchar(255),
AREA varchar(255),
DATE_1 date
);
INSERT INTO birds (SPECIES, AGE, BIRD_TRACKING_ID, AREA, DATE_1)
VALUES ('eagle', 'ad', null, 'A03', '2021-06-02'),
('merl', 'ad', 'B_mer_01', 'A03', '2021-07-01'),
('owl', 'jv', null, 'A04', '2021-06-11'),
('penguin', 'jv', 'B_pen_21', 'A04', '2021-07-01'),
('eagle', 'juv', null, 'A03', '2021-06-15'),
('eagle', 'ad', 'B_eag_16', 'A02', '2021-06-02'),
('merl', 'ad', null, 'A03', '2021-08-01'),
('owl', 'jv', 'B_owl_01', 'A02', '2021-02-01'),
('penguin', 'jv', 'B_pen_23', 'A04', '2021-04-17'),
('penguin', 'jv', null, 'A01', '2021-07-15'),
('eagle', 'ad', 'B_eag_23', 'A01', '2021-04-11'),
('eagle', 'ad', 'B_eag_11', 'A03', '2021-01-01')
;
CREATE TABLE trees (
TREE varchar(255),
DESCR varchar(255),
TREE_ID varchar(255),
BIRD_ID varchar(255)
);
INSERT INTO trees (TREE, DESCR, TREE_ID, BIRD_ID)
VALUES ('oak tree', 'd', 'T_2021_1a', 'B_eag_11'),
('birch', 'v', 'T_2021_2a', 'B_mer_01'),
('oak tree', 'v', 'T_2021_3a', 'B_owl_01'),
('larch', 'v', 'T_2021_4a', 'B_pen_23'),
('larch', 'v', 'T_2021_5d', 'B_pen_23'),
('birch', 'd', 'T_2021_5a', 'B_eag_11')
;
我想要的是计算所有按面积和种类分组的鸟类种类。到目前为止这很简单。
但在下一步中,我想从 t2
获取树 ID。我这样做了:
select
B_spec,
AMOUNT,
TREE,
B_age,
B_age_juv,
B_age_ad,
B_track,
B_area,
date1
from(
select
SPECIES as B_spec,
count(SPECIES) as AMOUNT,
AGE as B_age,
count(case when AGE = 'juv' then 1 end) as B_age_juv,
count(case when AGE = 'ad' then 1 end) as B_age_ad,
BIRD_TRACKING_ID as B_track,
AREA as B_area,
DATE_1 as date1,
group_concat(TREE_ID) as TREE
from birds
left join trees t2
on BIRD_TRACKING_ID = t2.BIRD_ID
group by B_area, B_spec
order by B_spec asc
) t1
得到了:
很明显是乱七八糟的,数错了。
我想要的是字段 TREE
中那只鸟访问过的所有树的树 ID。
此外,最好在一行中计算特定鸟类的数量,在另一行中计算访问过一棵树的鸟。
例如在 A03
区域我有 3 只老鹰。 2 个没有跟踪 ID,一个有跟踪 ID。所以 A03 上 3 只老鹰的输出应该是:
B_spec |TREE |AMOUNT| B_age_juv |B_age_ad |B_area |date1
---------------------------------------------------------------------------
eagle |null |2 | 1 |1 |A03 |2021-06-02
eagle |T_2021_1a,T_2021_5a |1 | 0 |1 |A03 |2021-01-01
该日期应为在该特定区域首次观察到该物种鸟类的日期。在 2021-06-02 和 2021-06-15 上看到没有跟踪 ID 的 A3 上的老鹰。所以第一行有 2021-06-02 作为 date1
.
数据不真实,企鹅不会飞。而我只能在QGIS中使用SQLite。
您应该为没有 BIRD_TRACKING_ID
的鸟类再创建一个分组级别并使用条件聚合:
SELECT b.SPECIES B_spec,
GROUP_CONCAT(t.TREE_ID) TREE,
COUNT(DISTINCT b.rowid) AMOUNT,
COUNT(DISTINCT CASE WHEN AGE = 'juv' THEN b.rowid END) B_age_juv,
COUNT(DISTINCT CASE WHEN AGE = 'ad' THEN b.rowid END) B_age_ad,
b.AREA B_area,
MIN(b.DATE_1) date1
FROM birds b LEFT JOIN trees t
ON b.BIRD_TRACKING_ID = t.BIRD_ID
GROUP BY B_area, B_spec, b.BIRD_TRACKING_ID IS NOT NULL
ORDER BY B_spec;
参见demo。
我数了不同日期和地区的鸟类。有些鸟有一个跟踪 ID。
这给了我一个 table 和这个 header。 t1
:
SPECIES | AGE | BIRD_TRACKING_ID | AREA | DATE_1
------------------------------------------------
| | | |
然后我们观察了鸟类,并记录了它们降落的树木。每棵树都有一个唯一的 ID。一只鸟本可以拜访过 none,一只鸟或几棵树。这给了我 table t2
这个 header:
TREE |DESCR |TREE_ID |BIRD_ID
------------------------------
| | |
CREATE TABLE birds (
SPECIES varchar(255),
AGE varchar(255),
BIRD_TRACKING_ID varchar(255),
AREA varchar(255),
DATE_1 date
);
INSERT INTO birds (SPECIES, AGE, BIRD_TRACKING_ID, AREA, DATE_1)
VALUES ('eagle', 'ad', null, 'A03', '2021-06-02'),
('merl', 'ad', 'B_mer_01', 'A03', '2021-07-01'),
('owl', 'jv', null, 'A04', '2021-06-11'),
('penguin', 'jv', 'B_pen_21', 'A04', '2021-07-01'),
('eagle', 'juv', null, 'A03', '2021-06-15'),
('eagle', 'ad', 'B_eag_16', 'A02', '2021-06-02'),
('merl', 'ad', null, 'A03', '2021-08-01'),
('owl', 'jv', 'B_owl_01', 'A02', '2021-02-01'),
('penguin', 'jv', 'B_pen_23', 'A04', '2021-04-17'),
('penguin', 'jv', null, 'A01', '2021-07-15'),
('eagle', 'ad', 'B_eag_23', 'A01', '2021-04-11'),
('eagle', 'ad', 'B_eag_11', 'A03', '2021-01-01')
;
CREATE TABLE trees (
TREE varchar(255),
DESCR varchar(255),
TREE_ID varchar(255),
BIRD_ID varchar(255)
);
INSERT INTO trees (TREE, DESCR, TREE_ID, BIRD_ID)
VALUES ('oak tree', 'd', 'T_2021_1a', 'B_eag_11'),
('birch', 'v', 'T_2021_2a', 'B_mer_01'),
('oak tree', 'v', 'T_2021_3a', 'B_owl_01'),
('larch', 'v', 'T_2021_4a', 'B_pen_23'),
('larch', 'v', 'T_2021_5d', 'B_pen_23'),
('birch', 'd', 'T_2021_5a', 'B_eag_11')
;
我想要的是计算所有按面积和种类分组的鸟类种类。到目前为止这很简单。
但在下一步中,我想从 t2
获取树 ID。我这样做了:
select
B_spec,
AMOUNT,
TREE,
B_age,
B_age_juv,
B_age_ad,
B_track,
B_area,
date1
from(
select
SPECIES as B_spec,
count(SPECIES) as AMOUNT,
AGE as B_age,
count(case when AGE = 'juv' then 1 end) as B_age_juv,
count(case when AGE = 'ad' then 1 end) as B_age_ad,
BIRD_TRACKING_ID as B_track,
AREA as B_area,
DATE_1 as date1,
group_concat(TREE_ID) as TREE
from birds
left join trees t2
on BIRD_TRACKING_ID = t2.BIRD_ID
group by B_area, B_spec
order by B_spec asc
) t1
得到了:
我想要的是字段 TREE
中那只鸟访问过的所有树的树 ID。
此外,最好在一行中计算特定鸟类的数量,在另一行中计算访问过一棵树的鸟。
例如在 A03
区域我有 3 只老鹰。 2 个没有跟踪 ID,一个有跟踪 ID。所以 A03 上 3 只老鹰的输出应该是:
B_spec |TREE |AMOUNT| B_age_juv |B_age_ad |B_area |date1
---------------------------------------------------------------------------
eagle |null |2 | 1 |1 |A03 |2021-06-02
eagle |T_2021_1a,T_2021_5a |1 | 0 |1 |A03 |2021-01-01
该日期应为在该特定区域首次观察到该物种鸟类的日期。在 2021-06-02 和 2021-06-15 上看到没有跟踪 ID 的 A3 上的老鹰。所以第一行有 2021-06-02 作为 date1
.
数据不真实,企鹅不会飞。而我只能在QGIS中使用SQLite。
您应该为没有 BIRD_TRACKING_ID
的鸟类再创建一个分组级别并使用条件聚合:
SELECT b.SPECIES B_spec,
GROUP_CONCAT(t.TREE_ID) TREE,
COUNT(DISTINCT b.rowid) AMOUNT,
COUNT(DISTINCT CASE WHEN AGE = 'juv' THEN b.rowid END) B_age_juv,
COUNT(DISTINCT CASE WHEN AGE = 'ad' THEN b.rowid END) B_age_ad,
b.AREA B_area,
MIN(b.DATE_1) date1
FROM birds b LEFT JOIN trees t
ON b.BIRD_TRACKING_ID = t.BIRD_ID
GROUP BY B_area, B_spec, b.BIRD_TRACKING_ID IS NOT NULL
ORDER BY B_spec;
参见demo。