如果query返回一行或多行,则返回行/行并退出

时间:2018-03-04 18:21:19

标签: sql postgresql

我有三个陈述。如果其中任何一个返回任何,我希望返回该查询并退出查询。

select * 
from   connexion
where  origin = 'Stockholm'
and    destination = 'Berlin';
-- IF IT RETURNS ONE OR MORE ROWS THEN RETURN ROW/ROWS AND EXIT, ELSE GO TO STATEMENT BELOW

select * 
from   connexion c1, connexion c2
where  c1.origin = 'Stockholm'
and    c2.destination = 'Berlin'
and    c1.destination = c2.origin;
-- IF IT RETURNS ONE OR MORE ROWS THEN RETURN ROW/ROWS AND EXIT, ELSE GO TO STATEMENT BELOW

select * 
from   connexion c1, connexion c2, connexion c3
where  c1.origin = 'Stockholm'
and    c3.destination = 'Berlin'
and    c1.destination = c2.origin
and    c2.destination = c3.origin;
-- IF IT RETURNS ONE OR MORE ROWS THEN RETURN ROW/ROWS AND EXIT, ELSE EXIT

这是创建数据库的查询。我想找回一个结果,我可以通过任何可用的连接从斯德哥尔摩到柏林。


create table busstop(
    city varchar(50),
    country varchar(50) not null,
    streetAddress varchar(50) not null,
    primary key (city)
);

create table driver( driverPnr varchar(13), name varchar(50) not null, address varchar(50) not null, phone varchar(12) not null, primary key (driverPnr) );

create table customer( customerPnr varchar(13), name varchar(50) not null, email varchar(50) not null, phone varchar(12) not null, primary key (customerPnr) );

create table connexion( connexionId serial not null, origin varchar(50) not null, destination varchar(50) not null, primary key (connexionId), foreign key (origin) references busstop(city), foreign key (destination) references busstop(city) );

create table trip( tripId serial not null, connexionId integer not null, departure timestamp not null, arrival timestamp not null, driverPnr varchar(13), priceAmount integer not null, seats integer not null, primary key (tripId), foreign key (connexionId) references connexion(connexionId), foreign key (driverPnr) references driver(driverPnr) );

create table booking( customerPnr varchar(13) not null, tripId integer not null, seats integer not null, primary key (customerPnr, tripId), foreign key (customerPnr) references customer(customerPnr), foreign key (tripId) references trip(tripId) );

insert into busstop(city, country, streetAddress) values ('Stockholm', 'Sweden', 'Byvägen 1'), ('Copenhagen', 'Denmark', 'Vesterbrogade 23'), ('Berlin', 'Germany', 'Europaplatz 4'), ('Amsterdam', 'Netherlands', 'Stationsplein 17'), ('Prague', 'Czech Republic', 'Wilsonova 10');

insert into connexion(origin, destination) values ('Stockholm', 'Copenhagen'), ('Copenhagen', 'Stockholm'),

('Copenhagen', 'Berlin'),
('Berlin', 'Copenhagen'),

('Copenhagen', 'Amsterdam'),
('Amsterdam', 'Copenhagen'),

('Berlin', 'Prague'),
('Prague', 'Berlin'),

('Amsterdam', 'Berlin'),
('Berlin', 'Amsterdam'),

('Amsterdam', 'Prague'),
('Prague', 'Amsterdam');

insert into trip(connexionId, departure, arrival, priceAmount, seats) values -- Exits on 2018-04-21

    -- Stockholm - Copenhagen / Copenhagen - Stockholm, 3 hours
    (1, '2018-04-22 07:00:00', '2018-04-22 10:00:00', 200, 35),
    (2, '2018-04-22 18:00:00', '2018-04-22 21:00:00', 200, 35),

    -- Copenhagen - Berlin / Berlin - Copenhagen, 7 hours
    (3, '2018-04-22 10:00:00', '2018-04-22 17:00:00', 500, 35),
    (4, '2018-04-22 11:00:00', '2018-04-22 18:00:00', 500, 35),

    -- Copenhagen - Amsterdam / Amsterdam - Copenhagen, 9 hours
    (5, '2018-04-22 10:00:00', '2018-04-22 19:00:00', 800, 35),
    (6, '2018-04-22 09:00:00', '2018-04-22 18:00:00', 800, 35),

    -- Berlin - Prague / Prague - Berlin, 4 hours
    (7, '2018-04-22 17:00:00', '2018-04-22 21:00:00', 300, 35),  
    (8, '2018-04-22 07:00:00', '2018-04-22 11:00:00', 300, 35),

    -- Amsterdam - Berlin / Berlin - Amsterdam, 7 hours
    (9, '2018-04-22 07:00:00', '2018-04-22 14:00:00', 500, 35),
    (10, '2018-04-22 14:00:00', '2018-04-22 21:00:00', 500, 35),

    -- Amsterdam - Prague / Prague - Amsterdam, 9 hours
    (11, '2018-04-22 05:00:00', '2018-04-22 14:00:00', 800, 35),
    (12, '2018-04-22 14:00:00', '2018-04-22 23:00:00', 800, 35);

如果我从斯德哥尔摩前往柏林,查询必须首先检查斯德哥尔摩和柏林之间是否有任何直接联系。如果不是,则必须检查是否存在与一个中途停留的连接,如果是,则为此检索一行。如果没有,请继续检查是否存在与两次中途停留的连接,并继续检查三次中途停留。 (没有人会想要从斯德哥尔摩到柏林超过三次中途停留..)..我很难解释我想要达到的目标,但我希望你明白这一点:)

4 个答案:

答案 0 :(得分:0)

到达,这是tsql
这只是直接或一站式

select 'Stockholm' as origin_, 'Berlin' as  destination_, *
from connexion c1 
join connexion c2
  on c1.origin = 'Stockholm'
 and (      c1.destination =  'Berlin'
        or (c1.destination <> 'Berlin' and c2.destination = 'Berlin') 
     ) 

答案 1 :(得分:0)

您可以使用多个连接执行此操作:

select c1.*, c2.*, c3.*
from connexion c1 left join
     connexion c2
     on c1.origin = 'Stockholm' and
        (c1.destination =  'Berlin' or
         (c1.destination <> 'Berlin' and c2.destination = 'Berlin') 
        ) left join
     connection c3
     on c2.destination = c3.destination and
        (c2.destination <> 'Berlin' and
         c1.destination <> 'Berlin'
        );

答案 2 :(得分:0)

这是sql server但是根据文档postgresql支持递归。

停止只是最后一站。这并没有显示所有停止。 Cnt是止损次数。

declare @t table (orig varchar(20), dest varchar(20)
                  , primary key (orig, dest));
insert into @t values
   ('Stockholm',  'Copenhagen'),
   ('Copenhagen', 'Stockholm'),
   ('Copenhagen', 'Berlin'),
   ('Berlin',     'Copenhagen'),
   ('Copenhagen', 'Amsterdam'),
   ('Amsterdam',  'Copenhagen'),
   ('Berlin',     'Prague'),
   ('Prague',     'Berlin'),
   ('Amsterdam',  'Berlin'),
   ('Berlin',     'Amsterdam'),
   ('Amsterdam',  'Prague'),
   ('Prague',     'Amsterdam');
with cte as 
( select t.orig, t.orig as 'stop', t.dest, 1 as cnt 
  from @t t 
  union all 
  select cte.orig, t.orig, t.dest, cnt + 1 
  from @t t 
  join cte 
    on cte.dest = t.orig 
   and t.dest <> cte.orig  --don't loop back home
   and cnt < 4
)
select * 
 from cte 
where orig = 'Stockholm' 
  and dest = 'Berlin'
order by cnt, cte.stop

这不会阻止路线中的循环。通过限制cnt,可以消除环路。它可以防止回到原来的城市。

答案 3 :(得分:-1)

您可以在SQL中使用GOTo语句。在下面的代码中,您可以分配您的查询计数,然后在if条件下,如果其大于0,则可以计数,然后是GOTO相应的查询。

DECLARE @a  Int
DECLARE @b  Int
SELECT  @a  =   10
SELECT  @b  =   5
BEGIN
    IF      @a>@0 GOTO  Greater
    IF      @b>0 GOTO   Lesser
END
Greater:    SELECT  @a
Lesser:     SELECT  @b