Skip to main content
Fixed casing on keywords and added a bit more detail.
Source Link
Nelson
  • 1.7k
  • 3
  • 15
  • 27

The following will perform an action similar to a FOREACHFOREACH cycle...:

createCREATE tableTABLE #TableOne (
    UserId varcharVARCHAR(5), 
    SalesNo intINT, 
    DateSale dateDATE, 
    MarkMet bitBIT);
insert
INSERT intoINTO #TableOne (
    UserId, 
    SalesNo, 
    DateSale, 
    MarkMet) valuesVALUES
('ec12', 22, '2017-01-01', 1),
('ec12', 4,  '2017-01-02', 0),
('ec12', 3,  '2017-01-03', 0),
('er11', 30, '2017-01-01', 1),
('er11', 22, '2017-01-02', 1),
('er11', 33, '2017-01-03', 1),
('ss33', 40, '2017-01-02', 1),
('ss33', 5,  '2017-01-10', 0)
 ;

declareDECLARE @RowCount intINT = (selectSELECT distinctDISTINCT countCOUNT(*) UserId fromFROM #TableOne);
declareDECLARE @i intINT = 11;
declareDECLARE @UserId varcharVARCHAR(5);
declareDECLARE @Temp tableTABLE (id intINT, userid varcharVARCHAR(5));

insertINSERT intoINTO @Temp (id, userid)
selectSELECT
    ROW_NUMBER() OVER(orderORDER byBY t.UserId) AS Id
    ,t.UserId
fromFROM (
    select distinctSELECT DISTINCT
        UserId 
    fromFROM #TableOne) t;

whileWHILE (@i <= @RowCount)
beginBEGIN
    setSET @UserId = (selectSELECT t.userid fromFROM @Temp t whereWHERE t.id = @i)

    --/************************************************/
 Generate   /* Build the logic to be iterated per each user */
    /* (generate CSV, Send Mail, etc)               */
    --/* ..                                             */
    /*    eg. selectSELECT * from                             */
    /*        FROM #TableOne where                       */
    /*        WHERE UserId = @UserId ...
               */
    --/* Send Mail                                            */
    /************************************************/

    setSET @i = @i + 1;
endEND

First it will create a temp table where to store each unique UserId and will assign them a pseudo-uid based on the ROW_COUNT, then it will iterate through this newly created table to get the UserId's one by one, at which point you'll be able to execute an action per record/UserId.

The following will perform an action similar to a FOREACH cycle...

create table #TableOne (UserId varchar(5), SalesNo int, DateSale date, MarkMet bit)
insert into #TableOne (UserId, SalesNo, DateSale, MarkMet) values
('ec12', 22, '2017-01-01', 1),
('ec12', 4, '2017-01-02', 0),
('ec12', 3, '2017-01-03', 0),
('er11', 30, '2017-01-01', 1),
('er11', 22, '2017-01-02', 1),
('er11', 33, '2017-01-03', 1),
('ss33', 40, '2017-01-02', 1),
('ss33', 5, '2017-01-10', 0)
 

declare @RowCount int = (select distinct count(*) UserId from #TableOne)
declare @i int = 1
declare @UserId varchar(5)
declare @Temp table (id int, userid varchar(5))

insert into @Temp (id, userid)
select
    ROW_NUMBER() OVER(order by t.UserId) AS Id
    ,t.UserId
from (
    select distinct 
    UserId 
    from #TableOne) t;

while (@i <= @RowCount)
begin
    set @UserId = (select t.userid from @Temp t where t.id = @i)

    -- Generate CSV
    -- ... select * from #TableOne where UserId = @UserId ...

    -- Send Mail

    set @i = @i + 1;
end

The following will perform an action similar to a FOREACH cycle:

CREATE TABLE #TableOne (
    UserId VARCHAR(5), 
    SalesNo INT, 
    DateSale DATE, 
    MarkMet BIT);

INSERT INTO #TableOne (
    UserId, 
    SalesNo, 
    DateSale, 
    MarkMet) VALUES
('ec12', 22, '2017-01-01', 1),
('ec12', 4,  '2017-01-02', 0),
('ec12', 3,  '2017-01-03', 0),
('er11', 30, '2017-01-01', 1),
('er11', 22, '2017-01-02', 1),
('er11', 33, '2017-01-03', 1),
('ss33', 40, '2017-01-02', 1),
('ss33', 5,  '2017-01-10', 0);

DECLARE @RowCount INT = (SELECT DISTINCT COUNT(*) UserId FROM #TableOne);
DECLARE @i INT = 1;
DECLARE @UserId VARCHAR(5);
DECLARE @Temp TABLE (id INT, userid VARCHAR(5));

INSERT INTO @Temp (id, userid)
SELECT
    ROW_NUMBER() OVER(ORDER BY t.UserId) AS Id
    ,t.UserId
FROM (
    SELECT DISTINCT
        UserId 
    FROM #TableOne) t;

WHILE (@i <= @RowCount)
BEGIN
    SET @UserId = (SELECT t.userid FROM @Temp t WHERE t.id = @i)

    /************************************************/
    /* Build the logic to be iterated per each user */
    /* (generate CSV, Send Mail, etc)               */
    /*                                              */
    /*    eg. SELECT *                              */
    /*        FROM #TableOne                        */
    /*        WHERE UserId = @UserId                */
    /*                                              */
    /************************************************/

    SET @i = @i + 1;
END

First it will create a temp table where to store each unique UserId and will assign them a pseudo-uid based on the ROW_COUNT, then it will iterate through this newly created table to get the UserId's one by one, at which point you'll be able to execute an action per record/UserId.

Source Link
Nelson
  • 1.7k
  • 3
  • 15
  • 27

The following will perform an action similar to a FOREACH cycle...

create table #TableOne (UserId varchar(5), SalesNo int, DateSale date, MarkMet bit)
insert into #TableOne (UserId, SalesNo, DateSale, MarkMet) values
('ec12', 22, '2017-01-01', 1),
('ec12', 4, '2017-01-02', 0),
('ec12', 3, '2017-01-03', 0),
('er11', 30, '2017-01-01', 1),
('er11', 22, '2017-01-02', 1),
('er11', 33, '2017-01-03', 1),
('ss33', 40, '2017-01-02', 1),
('ss33', 5, '2017-01-10', 0)


declare @RowCount int = (select distinct count(*) UserId from #TableOne)
declare @i int = 1
declare @UserId varchar(5)
declare @Temp table (id int, userid varchar(5))

insert into @Temp (id, userid)
select
    ROW_NUMBER() OVER(order by t.UserId) AS Id
    ,t.UserId
from (
    select distinct 
    UserId 
    from #TableOne) t;

while (@i <= @RowCount)
begin
    set @UserId = (select t.userid from @Temp t where t.id = @i)

    -- Generate CSV
    -- ... select * from #TableOne where UserId = @UserId ...

    -- Send Mail

    set @i = @i + 1;
end