Sql 如何删除重复的结果
给定以下模式:Sql 如何删除重复的结果,sql,postgresql,Sql,Postgresql,给定以下模式: CREATE TABLE IF NOT EXISTS companies ( id serial, name text NOT NULL, PRIMARY KEY (id) ); CREATE TABLE IF NOT EXISTS cars ( id serial, make text NOT NULL, year integer NOT NULL, company_id INTEGER REFERENCES companies(id),
CREATE TABLE IF NOT EXISTS companies (
id serial,
name text NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE IF NOT EXISTS cars (
id serial,
make text NOT NULL,
year integer NOT NULL,
company_id INTEGER REFERENCES companies(id),
PRIMARY KEY (id)
);
INSERT INTO companies (id, name) VALUES
(1, 'toyota'),
(2, 'chevy');
INSERT INTO cars (make, year, company_id) VALUES
('silverado', 1995, 2),
('malibu', 1999, 2),
('tacoma', 2017, 1),
('custom truck', 2010, null),
('van custom', 2005, null);
如何为汽车选择行,仅显示给定公司的最新汽车
e、 g
输出
make | model | year
--------------+--------+------
custom truck | | 2010
malibu | chevy | 1999
silverado | chevy | 1995
tacoma | toyota | 2017
van custom | | 2005
但我只想展示最新的“雪佛兰”,例如
并且仍然能够按“制造”进行排序,并显示没有空公司id的汽车
小提琴链接:
借助常用的表表达式和行数函数,我们可以得到所需的输出,下面是给出所需输出的查询
WITH temp AS
(SELECT
make
, companies.name AS model
, year
, row_number() over(PARTITION BY coalesce(companies.name, make) ORDER BY year desc) as rnk
FROM
cars
left join
companies
ON
companies.id = cars.company_id
)
SELECT
make
, model
, year
FROM
temp
WHERE
rnk = 1
;
借助常用的表表达式和行数函数,我们可以得到所需的输出,下面是给出所需输出的查询
WITH temp AS
(SELECT
make
, companies.name AS model
, year
, row_number() over(PARTITION BY coalesce(companies.name, make) ORDER BY year desc) as rnk
FROM
cars
left join
companies
ON
companies.id = cars.company_id
)
SELECT
make
, model
, year
FROM
temp
WHERE
rnk = 1
;
SQL可以基于集合数学(离散数学)完成。因此,您需要所有汽车的集合减去其年份小于给定公司id的最大年份的汽车集合 所有车辆的集合:
select * from cars
年份小于给定公司id的最大年份的所有车辆的集合:
select a.id from cars a, cars b where a.company_id = b.company_id and a.year < b.year
SQL可以基于集合数学(离散数学)完成。因此,您需要所有汽车的集合减去其年份小于给定公司id的最大年份的汽车集合 所有车辆的集合:
select * from cars
年份小于给定公司id的最大年份的所有车辆的集合:
select a.id from cars a, cars b where a.company_id = b.company_id and a.year < b.year
在Postgres中,最好使用
distinct on
:
select distinct on (co.id) ca.*, co.name as model
from cars ca left join
companies co
on ca.company_id = co.id
order by co.id, ca.year desc;
DISTINCT ON
是非常方便的Postgres语法。它在括号中为每个组合保留一行。具体行由ORDER by
子句确定
但是,您有一个难题,因为co.id
可以是null
。在这种情况下,你似乎想让所有的车都无人陪伴
因此:
或者更简单地使用union all
:
-- get the ones with a company
select distinct on (co.id) ca.*, co.name
from cars ca join
companies co
on ca.company_id = co.id
union all
-- get the ones with no company
select ca.*, null
from cars ca
where ca.company_id is null
order by year desc;
在其他数据库中,这通常使用行编号()来完成:
在Postgres中,最好使用distinct on
:
select distinct on (co.id) ca.*, co.name as model
from cars ca left join
companies co
on ca.company_id = co.id
order by co.id, ca.year desc;
DISTINCT ON
是非常方便的Postgres语法。它在括号中为每个组合保留一行。具体行由ORDER by
子句确定
但是,您有一个难题,因为co.id
可以是null
。在这种情况下,你似乎想让所有的车都无人陪伴
因此:
或者更简单地使用union all
:
-- get the ones with a company
select distinct on (co.id) ca.*, co.name
from cars ca join
companies co
on ca.company_id = co.id
union all
-- get the ones with no company
select ca.*, null
from cars ca
where ca.company_id is null
order by year desc;
在其他数据库中,这通常使用行编号()来完成:
您的cars
表没有model
,但这在您的结果集中。我使用model
作为公司的别名。在示例中,name
选择query您的cars
表没有model
,但这在您的结果集中。我使用model
作为公司的别名companys.name
在示例中选择query可以按品牌或年份对不同的解决方案进行排序吗?@schpetDISTINCT ON
使用ORDER BY
定义结果集中的行。如果您想要不同的最终排序,则需要一个子查询/CTE和一个附加的ORDER BY
。DISTINCT ON解决方案能否按品牌或年份排序?@schpetDISTINCT ON
使用ORDER BY
定义结果集中的行。如果您想要不同的最终排序,则需要一个子查询/CTE和一个附加的orderby
。
select ca.*
from (select ca.*, co.name as model,
row_number() over (partition by co.id,
case when co.id is null then ca.id end
order by year desc
) as seqnum
from cars ca left join
companies co
on ca.company_id = co.id
) ca
where seqnum = 1