我对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的所有值。
对于记录,我只有对数据库的只读访问权限,所以我无法创建一个程序(这是我的另一个想法)。
答案 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
最后,要在
中添加问题的原始部分
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
语句。