首先,请不要对我抱怨蹩脚的数据库结构。我们都有必须处理的事情,我们无法改变,我继承了这些在应用程序中根深蒂固的表。
考虑这两个表:
Personnel
+-----+-------+--------------+
| ID | Name | TECHNIQUE_ID |
+-----+-------+--------------+
| 134 | Bob | 1,2,4 |
+-----+-------+--------------+
| 135 | Mary | 1,3,4 |
+-----+-------+--------------+
| 136 | Frank | 2 |
+-----+-------+--------------+
Techniques
+-----+----------+
| ID | Name |
+-----+----------+
| 1 | Fishing |
+-----+----------+
| 2 | Archery |
+-----+----------+
| 3 | Bowling |
+-----+----------+
| 4 | Hiking |
+-----+----------+
我需要的是每个人的列表,其中包含他们执行的技术的逗号分隔列表。基本上将“1,3,4”变成“钓鱼,保龄球,徒步旅行”。
我可以通过嵌套查询在CF代码中执行此操作,但报表有数千行...这意味着它可能只为一个报表运行数万个查询。我宁愿在一个查询中完成所有操作。
答案 0 :(得分:2)
执行2个单独的查询,其中一个Personnel
表和一个Techniques
。
将技术查询结果处理为关联数组,其中索引是ID,值是名称。
输出Personnel.Technique_ID字段时,将逗号分隔值作为列表处理。循环遍历列表中的每个项目,并输出Techniques关联数组的值。
答案 1 :(得分:1)
您可以使用like
:
select p.*
from Personnel p join
Techniques t
on ','+ p.TECHNIQUE_ID+',' like '%,'+cast(t.id as varchar(255))+',%'
你真的需要这个连接字符串吗?或者单独的行是否足够好?
答案 2 :(得分:0)
<强>更新强>
另一种可能性是将Gordon的LIKE代码与XML Path trick结合起来,以便在一个查询中返回所有内容。 (我怀疑其中任何一个都是真正大表的速度恶魔,但考虑到你继承的模式......这是可以预期的。)
SELECT p.id,
STUFF( ( SELECT ','+ cast(name as varchar(10))
FROM Techniques t
WHERE ','+ p.Technique_ID+',' LIKE '%,'+ cast(t.id as varchar(255)) +',%'
FOR XML path('')
)
, 1,1,'') TechniqueList
FROM Personnel p
(不是一个完整的答案,但评论太长了......)
如果您只显示信息,则可以将Gordon's query与分组cfoutput
合并,以生成所需的输出。 (请务必订购结果Personnel.name
然后techniques.name
)
<强>代码:强>
<cfoutput query="yourQuery" group="id">
<cfset skills = []>
<cfoutput>
<cfset arrayAppend(skills, skillTitle)>
</cfoutput>
NAME: #name# |
SKILLS: #arrayToList(skills)#<br>
</cfoutput>
<强>结果:强>
NAME: Bob | SKILLS: Archery,Fishing,Hiking
NAME: Frank | SKILLS: Archery
NAME: Mary | SKILLS: Bowling,Fishing,Hiking