sybase while循环辅助

时间:2014-08-11 17:58:16

标签: sql loops sybase

我对SQL和Sybase有基本的了解,这是我第一次尝试循环。我在这里尝试了几个建议,并将以下内容放在一起

 DECLARE @district varchar(2), @numSchools int, @sc_cd varchar(2)
 SELECT @district = 'MS', @numSchools = 1

 SET rowcount 0
 SELECT supv_clas_cd INTO #MyTemp
     FROM t_supv_class
     WHERE eff_dt IS NULL

 DECLARE @rowsaf INT
 SELECT @rowsaf = @@rowcount FROM #MyTemp

 WHILE @rowsaf > 1
 BEGIN
     SET rowcount 1
     SELECT @sc_cd = supv_clas_cd FROM #MyTemp
     SET rowcount 0
     DELETE #MyTemp WHERE @sc_cd = supv_clas_cd
     SELECT @rowsaf = @@rowcount FROM #MyTemp

     SELECT TOP @numSchools
         s.nm_tx AS 'School Name', @sc_cd AS 'Supv Class'
        FROM t_Schools s
        LEFT OUTER JOIN t_supv_class sc ON sc.supv_clas_cd = s.supv_clas_cd
        WHERE supv_clas_cd = @sc_cd
        AND s.csrv_cd = @district
 END 
 SET rowcount 0

我试图做的是避免大量只有“supv_clas_cd”发生变化的UNION。 基本上,为每个给定的supv_clas返回一定数量的学校名称(可以随着表的编辑而改变)。

临时表#MyTemp平均有40行。 并非所有“supv_clas_cd”和“crsv_cd”的组合都有值,但是TRY / CATCH似乎并不希望。

任何人都可以帮助我让这个循环工作吗?或者告诉我我做错了什么?

或者只是对所有supv_clas_cd进行硬编码并将结果联合起来比在环绕所有这些内容时更好的解决方案?

我最初的想法是/是     DECLARE @district varchar(2),@ numSchools int     SELECT @district ='MS',@ numSchools = 1

SELECT TOP @numSchools
    s.nm_tx
    FROM t_Schools s
    LEFT OUTER JOIN t_supv_class sc ON sc.supv_clas_cd = s.supv_clas_cd
    WHERE supv_clas_cd = 'CC'
    AND s.csrv_cd = @district

UNION

SELECT TOP @numSchools
    s.nm_tx
    FROM t_Schools s
    LEFT OUTER JOIN t_supv_class sc ON sc.supv_clas_cd = s.supv_clas_cd
    WHERE supv_clas_cd = 'CH'
    AND s.csrv_cd = @district

UNION

SELECT TOP @numSchools
    s.nm_tx
    FROM t_Schools s
    LEFT OUTER JOIN t_supv_class sc ON sc.supv_clas_cd = s.supv_clas_cd
    WHERE supv_clas_cd = 'CO'
    AND s.csrv_cd = @district

UNION

SELECT TOP @numSchools
    s.nm_tx
    FROM t_Schools s
    LEFT OUTER JOIN t_supv_class sc ON sc.supv_clas_cd = s.supv_clas_cd
    WHERE supv_clas_cd = 'CT'
    AND s.csrv_cd = @district

UNION

SELECT TOP @numSchools
    s.nm_tx
    FROM t_Schools s
    LEFT OUTER JOIN t_supv_class sc ON sc.supv_clas_cd = s.supv_clas_cd
    WHERE supv_clas_cd = 'DA'
    AND s.csrv_cd = @district

UNION

SELECT TOP @numSchools
    s.nm_tx
    FROM t_Schools s
    LEFT OUTER JOIN t_supv_class sc ON sc.supv_clas_cd = s.supv_clas_cd
    WHERE supv_clas_cd = 'DB'
    AND s.csrv_cd = @district

UNION

SELECT TOP @numSchools
    s.nm_tx
    FROM t_Schools s
    LEFT OUTER JOIN t_supv_class sc ON sc.supv_clas_cd = s.supv_clas_cd
    WHERE supv_clas_cd = 'DI'
    AND s.csrv_cd = @district

UNION

SELECT TOP @numSchools
    s.nm_tx
    FROM t_Schools s
    LEFT OUTER JOIN t_supv_class sc ON sc.supv_clas_cd = s.supv_clas_cd
    WHERE supv_clas_cd = 'DJ'
    AND s.csrv_cd = @district

UNION

SELECT TOP @numSchools
    s.nm_tx
    FROM t_Schools s
    LEFT OUTER JOIN t_supv_class sc ON sc.supv_clas_cd = s.supv_clas_cd
    WHERE supv_clas_cd = 'DM'
    AND s.csrv_cd = @district

UNION

SELECT TOP @numSchools
    s.nm_tx
    FROM t_Schools s
    LEFT OUTER JOIN t_supv_class sc ON sc.supv_clas_cd = s.supv_clas_cd
    WHERE supv_clas_cd = 'DS'
    AND s.csrv_cd = @district

UNION

SELECT TOP @numSchools
    s.nm_tx
    FROM t_Schools s
    LEFT OUTER JOIN t_supv_class sc ON sc.supv_clas_cd = s.supv_clas_cd
    WHERE supv_clas_cd = 'DV'
    AND s.csrv_cd = @district

UNION

SELECT TOP @numSchools
    s.nm_tx
    FROM t_Schools s
    LEFT OUTER JOIN t_supv_class sc ON sc.supv_clas_cd = s.supv_clas_cd
    WHERE supv_clas_cd = 'FB'
    AND s.csrv_cd = @district

UNION

SELECT TOP @numSchools
    s.nm_tx
    FROM t_Schools s
    LEFT OUTER JOIN t_supv_class sc ON sc.supv_clas_cd = s.supv_clas_cd
    WHERE supv_clas_cd = 'FO'
    AND s.csrv_cd = @district

UNION

SELECT TOP @numSchools
    s.nm_tx
    FROM t_Schools s
    LEFT OUTER JOIN t_supv_class sc ON sc.supv_clas_cd = s.supv_clas_cd
    WHERE supv_clas_cd = 'LC'
    AND s.csrv_cd = @district

UNION

SELECT TOP @numSchools
    s.nm_tx
    FROM t_Schools s
    LEFT OUTER JOIN t_supv_class sc ON sc.supv_clas_cd = s.supv_clas_cd
    WHERE supv_clas_cd = 'LH'
    AND s.csrv_cd = @district

UNION

SELECT TOP @numSchools
    s.nm_tx
    FROM t_Schools s
    LEFT OUTER JOIN t_supv_class sc ON sc.supv_clas_cd = s.supv_clas_cd
    WHERE supv_clas_cd = 'LL'
    AND s.csrv_cd = @district

UNION

SELECT TOP @numSchools
    s.nm_tx
    FROM t_Schools s
    LEFT OUTER JOIN t_supv_class sc ON sc.supv_clas_cd = s.supv_clas_cd
    WHERE supv_clas_cd = 'LN'
    AND s.csrv_cd = @district

UNION

SELECT TOP @numSchools
    s.nm_tx
    FROM t_Schools s
    LEFT OUTER JOIN t_supv_class sc ON sc.supv_clas_cd = s.supv_clas_cd
    WHERE supv_clas_cd = 'LT'
    AND s.csrv_cd = @district

UNION

SELECT TOP @numSchools
    s.nm_tx
    FROM t_Schools s
    LEFT OUTER JOIN t_supv_class sc ON sc.supv_clas_cd = s.supv_clas_cd
    WHERE supv_clas_cd = 'MC'
    AND s.csrv_cd = @district

UNION

SELECT TOP @numSchools
    s.nm_tx
    FROM t_Schools s
    LEFT OUTER JOIN t_supv_class sc ON sc.supv_clas_cd = s.supv_clas_cd
    WHERE supv_clas_cd = 'MH'
    AND s.csrv_cd = @district

UNION

SELECT TOP @numSchools
    s.nm_tx
    FROM t_Schools s
    LEFT OUTER JOIN t_supv_class sc ON sc.supv_clas_cd = s.supv_clas_cd
    WHERE supv_clas_cd = 'ML'
    AND s.csrv_cd = @district

UNION

SELECT TOP @numSchools
    s.nm_tx
    FROM t_Schools s
    LEFT OUTER JOIN t_supv_class sc ON sc.supv_clas_cd = s.supv_clas_cd
    WHERE supv_clas_cd = 'MN'
    AND s.csrv_cd = @district

UNION

SELECT TOP @numSchools
    s.nm_tx
    FROM t_Schools s
    LEFT OUTER JOIN t_supv_class sc ON sc.supv_clas_cd = s.supv_clas_cd
    WHERE supv_clas_cd = 'MT'
    AND s.csrv_cd = @district

这假设“WHERE supv_clas_cd”没有改变,如果我需要更改SELECT语句,我必须在每个位置都这样做。

数据样本看起来像

t_supv_class|t_Schools
supv_clas_cd|nm_tx supv_clas_cd CC |Acidlog DB CH |Alexander FB CO |Amazing CT CT |Arthur FB DA |Babel CT DB |Babica FB DI |Bambleweeny DB DJ |Bang CH DM |Beeblebrox CT DS |Beneath CH DV |Betelgeuse DB FB |Blagulon CT FO |Blaster CH LC |Both DB LH |Brain CH LL |Bugblatter CH LN |By CH LT |Clare DB MC |Cos CH MH |Could CH ML |Damogran CT MN |Dark DB MT |Deep CH

从这个样本中,我想要

Acidlog
Alexander
Amazing
Bambleweeny
Bang

我正在考虑循环,因此集中SELECT语句以进行维护和重用,以及不对硬编码t_supv_clas.supv_clas_cd的所有值。

对于记录,我只有对数据库的只读访问权限,所以我无法创建一个程序(这是我的另一个想法)。

2 个答案:

答案 0 :(得分:0)

试试这个,我不确定你希望如何看到" Bambleweeny",也许我误解了一些东西,但是" Bambleweeny"与supv_class_cd" DB"相关联," Acidlog"。

为了实现结果并允许@numSchools影响每个supv_class_cd返回的行数,我需要创建一个"密集等级"。在Oracle和SQL Server中我相信 有这样一个关键字,但在Sybase ASE中没有,所以它在这里伪造:

            (
                select
                        count(*) as row_id
                    from
                        t_schools s1
                    where
                        s.nm_tx >= s1.nm_tx
                    and s1.supv_class_cd = t.supv_class_cd
            ) as row_id

count(*)计算小于当前行的行数,并与统一外表#MyTemp中的supv_class_cd列匹配。在这种情况下,密集等级超过nm_tx列。

使用连接迭代#MyTemp中的supv_class_cd值集合,这将替换原始问题中的循环。

    select
            s.nm_tx,
            s.supv_class_cd,
            (
                select
                        count(*) as row_id
                    from
                        t_schools s1
                    where
                        s.nm_tx >= s1.nm_tx
                    and s1.supv_class_cd = t.supv_class_cd
            ) as row_id
        from
            t_schools s,
            #MyTemp t
        where
            s.supv_class_cd = t.supv_class_cd

最后,要在

中添加问题的原始部分
  • 使用t_supv_class的外连接,这是指定的
  • 每个supv_class_cd
  • 的行数限制
  • 创建#MyTemp,再次指定
  • 声明和设置参数

declare
    @numSchools int,
    @district char(2)

select
    @numSchools = 1,
    @district = 'MS'

select distinct 
        supv_class_cd
    into #MyTemp
    from t_supv_class
    where
        eff_dt is null

select
        x.nm_tx as School_name,
        x.supv_class_cd as Supv_class        
    from
    (
        select
                s.nm_tx,
                s.supv_class_cd,
                (
                    select
                            count(*) as row_id
                        from
                            t_schools s1
                        where
                            s.nm_tx >= s1.nm_tx
                        and s1.supv_class_cd = t.supv_class_cd
                ) as row_id
            from
                t_schools s,
                #MyTemp t
            where
                s.supv_class_cd = t.supv_class_cd
    ) x
    left outer join t_supv_class sc on sc.supv_class_cd = x.supv_class_cd
    where
        x.row_id <= @numSchools
go

我希望这能在适当的时候找到你,或者至少为你提供一些帮助。

答案 1 :(得分:0)

我发现以下声明有两次奇怪的发生:

SELECT @rowsaf = @@rowcount FROM #MyTemp

我会用:

SELECT @rowsaf = count(*) FROM #MyTemp

@@rowcount是一个系统变量,用于存储受最新可执行命令影响的记录数。它与表格中的行数无关 看看这是否能让您更接近理想的结果。绝对不建议使用每个代码值为1 sql的UNION语句。