SELECT 仅来自几个无序的相同行 SQL/PostgreSQL
SELECT only on row from a couple unordered identical rows SQL/PostgreSQL
我试图只获取给定下一个 table:
的两行中的一个
| fn1 | o1 | d1 | date | fn2 | o2 | d2 |
------------------------------------------------------
| 1 | ATL | PEK | 2018-09-29 | 7 | PEK | ATL |
| 7 | PEK | ATL | 2018-09-29 | 1 | ATL | PEK |
我将第一行称为 R1,第二行称为 R2。
在一般情况下,我需要检查:
R1.fn1 = R2.dn2 AND R1.fn2 = R2.fn1 AND R1.o1 = R1.d2 = R2.d1 = R2.o1 AND R1.d1 = R1.o2 = R2.o1 = R2.d2
AND R1.date = R2.date
如果我的 table 中任何 2 行给定的行都是如此,我需要将它们分组为仅一个。
我不知道是否有办法使用 Group By 或 Distinct 来解决它。
我试了好几次查询,但最终还是没能删除冗余。
为了提供更多信息,我将解释所提供的 table 的来源。我有以下 table:
CREATE TABLE flights (
flightNumber SERIAL PRIMARY KEY,
origin CHAR(3) REFERENCES airports(code),
destination CHAR(3) REFERENCES airports(code),
departureTime TIMESTAMP NOT NULL,
seatsNumber INT NOT NULL,
airlineAbv VARCHAR(10) REFERENCES airlines(abv));
我需要一个查询来检查当天可能的往返行程。
为此,我使用了:
CREATE VIEW AtoB AS
SELECT flightNumber fN1, origin o1, destination d1, departureTime::DATE dT1
FROM flights;
CREATE VIEW BtoA AS
SELECT flightNumber fN2, origin o2, destination d2, departureTime::DATE dT2
FROM flights;
CREATE VIEW AtoBtoA AS
SELECT * FROM AtoB, BtoA WHERE o1 = d2 AND o2 = d1 AND dT1 = dT2;
从最后一个查询中,我得到了与示例中的查询非常相似的 table。示例中的那个更简单一些,这样更容易解释我想要实现的概念。
希望我说清楚了我的问题。
Ps: 在这里你有我的整个数据库来查看设计。我想它可能会有用。
CREATE TABLE airports (
code CHAR(3) PRIMARY KEY,
city VARCHAR(30) NOT NULL
);
CREATE TABLE airlines (
name VARCHAR(30) NOT NULL,
abv VARCHAR(10) PRIMARY KEY
);
CREATE TABLE passengers (
id SERIAL PRIMARY KEY,
name VARCHAR(60) NOT NULL
);
CREATE TABLE flights (
flightNumber SERIAL PRIMARY KEY,
origin CHAR(3) REFERENCES airports(code),
destination CHAR(3) REFERENCES airports(code),
departureTime TIMESTAMP NOT NULL,
seatsNumber INT NOT NULL,
airlineAbv VARCHAR(10) REFERENCES airlines(abv)
);
CREATE TABLE bookings (
passengerId INT REFERENCES passengers(id),
bookDate TIMESTAMP NOT NULL,
price REAL NOT NULL,
flightId INT REFERENCES flights(flightNumber)
);
我不确定你的表格列表是什么。但是对于您的原始问题,您可以使用 union all
和 not exists
:
select t.*
from t
where fn1 < fn2 and o1 = d2 and d1 = o2 or
(o1 <> d2 or d1 <> o2)
union all
select t.*
from t t2
where fn1 > fn2 and o1 = d2 and d1 = o2 and
not exists (select 1
from t t2
where t2.fn1 = t.fn2 and t2.fn2 = t2.fn1 and
t2.o1 = t.d1 and t2.d1 = t.o1 and
t2.date = t.date
);
我试图只获取给定下一个 table:
的两行中的一个| fn1 | o1 | d1 | date | fn2 | o2 | d2 |
------------------------------------------------------
| 1 | ATL | PEK | 2018-09-29 | 7 | PEK | ATL |
| 7 | PEK | ATL | 2018-09-29 | 1 | ATL | PEK |
我将第一行称为 R1,第二行称为 R2。
在一般情况下,我需要检查:
R1.fn1 = R2.dn2 AND R1.fn2 = R2.fn1 AND R1.o1 = R1.d2 = R2.d1 = R2.o1 AND R1.d1 = R1.o2 = R2.o1 = R2.d2 AND R1.date = R2.date
如果我的 table 中任何 2 行给定的行都是如此,我需要将它们分组为仅一个。 我不知道是否有办法使用 Group By 或 Distinct 来解决它。 我试了好几次查询,但最终还是没能删除冗余。
为了提供更多信息,我将解释所提供的 table 的来源。我有以下 table:
CREATE TABLE flights (
flightNumber SERIAL PRIMARY KEY,
origin CHAR(3) REFERENCES airports(code),
destination CHAR(3) REFERENCES airports(code),
departureTime TIMESTAMP NOT NULL,
seatsNumber INT NOT NULL,
airlineAbv VARCHAR(10) REFERENCES airlines(abv));
我需要一个查询来检查当天可能的往返行程。 为此,我使用了:
CREATE VIEW AtoB AS
SELECT flightNumber fN1, origin o1, destination d1, departureTime::DATE dT1
FROM flights;
CREATE VIEW BtoA AS
SELECT flightNumber fN2, origin o2, destination d2, departureTime::DATE dT2
FROM flights;
CREATE VIEW AtoBtoA AS
SELECT * FROM AtoB, BtoA WHERE o1 = d2 AND o2 = d1 AND dT1 = dT2;
从最后一个查询中,我得到了与示例中的查询非常相似的 table。示例中的那个更简单一些,这样更容易解释我想要实现的概念。
希望我说清楚了我的问题。
Ps: 在这里你有我的整个数据库来查看设计。我想它可能会有用。
CREATE TABLE airports (
code CHAR(3) PRIMARY KEY,
city VARCHAR(30) NOT NULL
);
CREATE TABLE airlines (
name VARCHAR(30) NOT NULL,
abv VARCHAR(10) PRIMARY KEY
);
CREATE TABLE passengers (
id SERIAL PRIMARY KEY,
name VARCHAR(60) NOT NULL
);
CREATE TABLE flights (
flightNumber SERIAL PRIMARY KEY,
origin CHAR(3) REFERENCES airports(code),
destination CHAR(3) REFERENCES airports(code),
departureTime TIMESTAMP NOT NULL,
seatsNumber INT NOT NULL,
airlineAbv VARCHAR(10) REFERENCES airlines(abv)
);
CREATE TABLE bookings (
passengerId INT REFERENCES passengers(id),
bookDate TIMESTAMP NOT NULL,
price REAL NOT NULL,
flightId INT REFERENCES flights(flightNumber)
);
我不确定你的表格列表是什么。但是对于您的原始问题,您可以使用 union all
和 not exists
:
select t.*
from t
where fn1 < fn2 and o1 = d2 and d1 = o2 or
(o1 <> d2 or d1 <> o2)
union all
select t.*
from t t2
where fn1 > fn2 and o1 = d2 and d1 = o2 and
not exists (select 1
from t t2
where t2.fn1 = t.fn2 and t2.fn2 = t2.fn1 and
t2.o1 = t.d1 and t2.d1 = t.o1 and
t2.date = t.date
);