英文:
Sql server - comparison of all possible combinations and saving the result in another table
问题
我有一个简单的SQL查询,询问一个对象是否具有指定的特征。
举个简单的例子,我想要检查一组对象是否是双色、三色、四色的。所以我有可变的特征(取决于外部用户),在这个例子中,用户选择了颜色:红色('C1')、黄色('C2')、绿色('C3')、蓝色('C4')。他想知道是否有红-黄、红-绿、红-蓝...红-黄-绿...红-黄-蓝-绿(任何组合)的对象。
我的代码则分别查找具有共同特征的对象:
"SELECT [Object] FROM TableData WHERE [character A] = '" + C1 + "' INTERSECT SELECT [Object] FROM TableData WHERE [character A] = '" + C2 + "'";
接下来是:
"SELECT [Object] FROM TableData WHERE [character A] = '" + C1 + "' INTERSECT SELECT [Object] FROM TableData WHERE [character A] = '" + C3 + "'";
...
然后,我必须将所有找到的对象保存到一个新表中,为它们创建两个新的特定值:
- 对象正在寻找的颜色数量
- 识别颜色的类别(例如'C12' - 在给定情况下识别红-黄)
我的C#代码如下:
string sqlStatement = "INSERT INTO AnalysisTable (Colors, Object, level) VALUES (@val1,@val2,@val3)";
try
{
con.Open();
SqlCommand cmd = new SqlCommand(sqlStatement, con);
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("@val1", "C12");
cmd.Parameters.AddWithValue("@val2", C12[i].Object);
cmd.Parameters.AddWithValue("@val3", "2");
cmd.ExecuteNonQuery();
}
我逐个检查每种组合。这会生成大量的代码,我相信可以以某种方式简化...但我不知道如何做。
提前感谢您的任何帮助。
附:如果对象是红-黄-绿的,应该保存四次:
- 红-黄
- 红-绿
- 黄-绿
- 红-黄-绿
编辑:简化的结构:链接
在尝试简化代码时,遇到了“子查询返回多个值”的问题。我的核心代码避免了这个问题,因为它首先获取了单独查询的值,然后将它们添加在一起。我找不到解决方法。
为了更好地解释,程序代码在指定特征后比较数据集。
英文:
I have a simple sql query that asks if an object has the specified characteristics.
For simple example, I want to check if a group of objects is a double, triple, quadra color. And so I have variable characteristics (depending on the external user), in this example the user has chosen the colors: red ('C1'), yellow ('C2'), green ('C3'), blue ('C4'). And he wants to know if there are objects of red-yellow, red-green, red-blue ... red-yellow-green ... red-yellow-blue-green (any combination).
My code, in turn (in separate queries), looks for objects with common characteristics:
"SELECT [Object] FROM TableData WHERE [character A] = '" + C1 + "' INTERSECT SELECT [Object] FROM TableData WHERE [character A] = '" + C2 + "'";
next
"SELECT [Object] FROM TableData WHERE [character A] = '" + C1 + "' INTERSECT SELECT [Object] FROM TableData WHERE [character A] = '" + C3 + "'";
...
and then I have to save all found objects to a new table creating two new specific values for them
- how many colors the object is looking for
- category identifying colors (for example 'C12' - identifying red-yellow in a given case)
my code in C#
string sqlStatement = "INSERT INTO AnalysisTable (Colors, Object, level) VALUES (@val1,@val2,@val3)";
try
{
con.Open();
SqlCommand cmd = new SqlCommand(sqlStatement, con);
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("@val1", "C12");
cmd.Parameters.AddWithValue("@val2", C12[i].Object);
cmd.Parameters.AddWithValue("@val3", "2");
cmd.ExecuteNonQuery();
}
I check each combination one by one. It generates a lot of code and I'm sure it can be simplified somehow...
But i don't know how
Thanks in advance for any help
Ps. if object is red-yellow-green should save it four times as
- red-yellow
- red-green
- yellow-green
- red-yellow-green
Edit
simplified structure
https://dbfiddle.uk/8oUNkVdZ
In my attempts to simplify the code the problem is 'Subquery returned more than 1 value'. My core code gets around this because it fetches the values for a separate query first and then adds them. I couldn't find a workaround.
For a better explanation, the program code compares datasets after point specifying character.
答案1
得分: 1
也许这个任务更适合使用递归来解决。我将提供一个更简单(直接)的解决方案。
尝试这个。不使用临时表。
with colors2 as (
select c1, c2 from (values('white', 'black'), ('white', 'green'), ('white', 'red'),
('black', 'green'), ('black', 'red'), ('green', 'red')
) t(c1, c2)
),
colors3 as (
select c1, c2, c3 from (values('white', 'black', 'green'), ('white', 'black', 'red'),
('white', 'green', 'red'), ('black', 'green', 'red')
) t(c1, c2, c3)
),
colors4 as (
select c1, c2, c3, c4 from (values('white', 'black', 'green', 'red')
) t(c1, c2, c3, c4)
),
t2 as (
select [object]
,string_agg([character A], ',') colors
from TableData
group by [Object]
)
select object, c1, c2, '' c3, '' c4, colors
from t2 t
left join colors2 t2 on charindex(t2.c1, t.colors) > 0 and charindex(t2.c2, t.colors) > 0
where c1 is not null
union all
select object, c1, c2, c3, '' c4, colors
from t2 t
left join colors3 t3 on charindex(t3.c1, t.colors) > 0 and charindex(t3.c2, t.colors) > 0
and charindex(t3.c3, t.colors) > 0
where c1 is not null
union all
select object, c1, c2, c3, c4, colors
from t2 t
left join colors4 t4 on charindex(t4.c1, t.colors) > 0 and charindex(t4.c2, t.colors) > 0
and charindex(t4.c3, t.colors) > 0 and charindex(t4.c4, t.colors) > 0
where c1 is not null
order by [Object]
查询结果:
object | c1 | c2 | c3 | c4 | colors |
---|---|---|---|---|---|
Object1 | white | black | red,white,green,black | ||
Object1 | white | green | red,white,green,black | ||
Object1 | white | red | red,white,green,black | ||
Object1 | black | green | red,white,green,black | ||
Object1 | black | red | red,white,green,black | ||
Object1 | green | red | red,white,green,black | ||
Object1 | white | black | green | red,white,green,black | |
Object1 | white | black | red | red,white,green,black | |
Object1 | white | green | red | red,white,green,black | |
Object1 | black | green | red | red,white,green,black | |
Object1 | white | black | green | red | red,white,green,black |
Object2 | green | red | red,green | ||
Object3 | white | red | white,red |
可以简单地排除具有null的对。
英文:
May be this task better solved by reсursion. I will offer a simpler (direct) solution.
Try this. Temporary table not used.
with colors2 as(
select c1,c2 from (values('white','black'),('white','green'),('white','red')
,('black','green'),('black','red')
,('green','red')
)t(c1,c2)
)
,colors3 as(
select c1,c2,c3 from (values('white','black','green'),('white','black','red')
,('white','green','red')
,('black','green','red')
)t(c1,c2,c3)
)
,colors4 as(
select c1,c2,c3,c4 from (values('white','black','green','red')
)t(c1,c2,c3,c4)
)
,t2 as(
select [object]
,string_agg([character A],',') colors
from TableData
group by [Object]
)
select object,c1,c2,'' c3,'' c4,colors
from t2 t
left join colors2 t2 on charindex(t2.c1,t.colors)>0 and charindex(t2.c2,t.colors)>0
where c1 is not null
union all
select object,c1,c2,c3,'' c4,colors
from t2 t
left join colors3 t3 on charindex(t3.c1,t.colors)>0 and charindex(t3.c2,t.colors)>0
and charindex(t3.c3,t.colors)>0
where c1 is not null
union all
select object,c1,c2,c3,c4,colors
from t2 t
left join colors4 t4 on charindex(t4.c1,t.colors)>0 and charindex(t4.c2,t.colors)>0
and charindex(t4.c3,t.colors)>0 and charindex(t4.c4,t.colors)>0
where c1 is not null
order by [Object]
Query result
object | c1 | c2 | c3 | c4 | colors |
---|---|---|---|---|---|
Object1 | white | black | red,white,green,black | ||
Object1 | white | green | red,white,green,black | ||
Object1 | white | red | red,white,green,black | ||
Object1 | black | green | red,white,green,black | ||
Object1 | black | red | red,white,green,black | ||
Object1 | green | red | red,white,green,black | ||
Object1 | white | black | green | red,white,green,black | |
Object1 | white | black | red | red,white,green,black | |
Object1 | white | green | red | red,white,green,black | |
Object1 | black | green | red | red,white,green,black | |
Object1 | white | black | green | red | red,white,green,black |
Object2 | green | red | red,green | ||
Object3 | white | red | white,red |
Pairs with null may be excluded simply.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论