如果列的值为0,则为T-SQL Foreach行

时间:2018-04-02 12:35:04

标签: sql-server tsql foreach

我是处理SQL查询的新手,我正在尝试检查来自Access denied for user 'root'...表的每个父级是否具有来自Parents表的所有子级的年龄。例如:

家长

Children

儿童

 Name        Id
John Smith   7

这是我到目前为止所做的:

Name            Age    ParentId
Sasha Smith     10       7
Johnny Smith     0       7

如果我要调用John Smith的函数(@parentId = 7),@ allOk的值应为0,因为他的一个孩子(Johnny)的年龄为0岁。如果所有孩子都有年龄> 0然后@allOk应该有1。

任何人都可以帮助我吗?据我了解,T-SQL不支持For Each ... Next,依此类推,那么我有哪些替代方案呢?

4 个答案:

答案 0 :(得分:2)

根本不需要CURSOR:

SELECT *
FROM Parents p
OUTER APPLY (SELECT CASE WHEN
                      COUNT(*) = COUNT(CASE WHEN c.Age > 0 THEN 1 END) THEN 1
                      ELSE 0
                    END AS res
             FROM Children c
             WHERE p.id = c.parent_id
            ) sub
 -- WHERE ....;

<强> DBFiddle Demo

  

据我了解,T-SQL并不支持For Each。

不是这样,For-Each是一种相关的子查询,例如:使用Gordon's answerOUTER APPLY中的内联语法。

答案 1 :(得分:2)

这是一个相对简单而有效的方法:

select p.*,
       (case when exists (select 1 from children c where c.parentid = p.id and c.age = 0
             then 1 else 0
        end) as flag
from p;

您只需执行以下操作即可实现此功能:

create function fnCheckChildren(
    @parentId int
)
returns int
begin 
    if (exists (select 1 from children where parentid = @parentid and age = 0)
       )
    begin
        return(0);
    end;
    return(1);
end;

答案 2 :(得分:0)

您可以尝试以下查询

CREATE FUNCTION fnCheckChildren(
    @parentId INT
)
RETURNS INT
BEGIN 
DECLARE @allOk INT

SET @allOk = CASE WHEN (select count(*) from Children where ParentId=@parentId AND Age > 0) > 1 THEN 1
                  ELSE 0 END

RETURN @allOk 
END

由于

答案 3 :(得分:0)

你也可能有一个没有孩子的案子。这将表明。

declare @P table (id int identity primary key, name varchar(20));
insert into @P (name) values ('John Smith'), ('Pat Jones'), ('Will Smith');
select * from @P;
declare @C table (id int identity primary key, parID int, name varchar(20), age int);
insert into @C (parID, name, age) values (1, 'jim', 12), (1, 'sally', 0), (2, 'bruce', 10);
select * from @C; 
select p.id, P.name 
     , count(c.id) as [child count]
     , case when MIN(c.age) <= 0 then 'childen with zero' else 'no children with zero' end as status
from @P p 
left join @C c 
on p.id = c.parID 
group by p.id, p.name;