简体   繁体   中英

Looping over the result in SQL Server

Example table

id  emplrcd effdt   country visited
------------------------------------
112233  0   10/9/2018   US
112233  1   10/10/2018  IND
112233  1   10/11/2018  BAN
112233  1   10/12/2018  PAK
112233  0   10/13/2018  US
112233  2   10/14/2018  IND
112233  2   10/16/2018  THA
112233  2   10/17/2018  SIN
112233  0   10/18/2018  US

223344  0   10/9/2018   US
223344  1   10/10/2018  IND
223344  1   10/11/2018  BAN
223344  1   10/12/2018  PAK
223344  0   10/13/2018  US
223344  2   10/14/2018  IND

I want to loop over certain result set from the query, eg id 112233 is from US, between two US country code where the country code represents the country he visited.

count(*) where country visited = US --> 3

Now I want to iterate over my result 3 times getting all the intermediate dates he went outside. Can this be done in a single SQL query or do I need something like cursor to do this?

Result for the above cursor or query should return the following rows

112233  1   10/10/2018  IND
112233  1   10/11/2018  BAN
112233  1   10/12/2018  PAK
112233  2   10/14/2018  IND
112233  2   10/16/2018  THA
112233  2   10/17/2018  SIN

223344  1   10/10/2018  IND
223344  1   10/11/2018  BAN
223344  1   10/12/2018  PAK

I would use window functions:

select t.*
from (select t.*,
             min(case when t.country = 'US' then t.effdt end) over (partition by t.id) as us_min_effdt,
             max(case when t.country = 'US' then t.effdt end) over (partition by t.id) as us_max_effdt
      from t
     ) t
where country <> 'US' and
      effdt >= us_min_effdt and efft < us_max_effdt;

Here is a solution using a CTE to set up your boundry conditions.

-------------------------
-- TEST SCHEMA

create table #datatable (id varchar(6), emplrcd int, effdt date, [country visited] varchar (3))

insert into #datatable values

('112233',0,'10/9/2018 ','US '),
('112233',1,'10/10/2018','IND'),
('112233',1,'10/11/2018','BAN'),
('112233',1,'10/12/2018','PAK'),
('112233',0,'10/13/2018','US '),
('112233',2,'10/14/2018','IND'),
('112233',2,'10/16/2018','THA'),
('112233',2,'10/17/2018','SIN'),
('112233',0,'10/18/2018','US '),
('223344',0,'10/9/2018 ','US '),
('223344',1,'10/10/2018','IND'),
('223344',1,'10/11/2018','BAN'),
('223344',1,'10/12/2018','PAK'),
('223344',0,'10/13/2018','US '),
('223344',2,'10/14/2018','IND')

-------------------------
-- QUERY

; WITH boundryDate AS 
(
    SELECT 
        id
         ,min (effdt) mindate
         , max(effdt) maxdate

     FROM
        #datatable
     WHERE
        [country visited] = 'US'
     GROUP BY
        id
)

SELECT
    *
FROM
    #datatable dt

    JOIN boundryDate bd
        on dt.id = bd.id
        and dt.effdt between bd.mindate and bd.maxdate
WHERE
    [country visited] <> 'US'

使用EXISTS()函数返回所有非“ US”行,其中EXISTS()之前为“ US”行,EXISTS()之后为“ US”行。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM