mysql - 如何从多个表中选择一个(或零个)条目,并将这些值添加在一起以匹配特定值?

标签 mysql sql-server algorithm

我会在这里说得更清楚。现在假设我有3个表,它们的内容如下:

table 1:
A    B    C    D    E    F    G
2    0    1    3    0    0    2
0    2    -1   0    0    1    0
4    0    0    2    1    0    0
0    0    3    0    2    0    5


table 2:
A    B    C    D    E    F    G
-1   2    3    3    0    4    0
3    0    0    2    0    0    1
1    0    1    -2   1    3    0
0    2    -3   0    3    0    0


table 3:
A    B    C    D    E    F    G
0    4    5    -1   0    2    0
0    -2   3    0    0    0    -4
3    0    0    -4   1    3    0
1    0    -1   5    2    0    6

现在我需要从每个表中选择零到一条目,其中一个或多个特定属性(A-G)的总和等于我指定的特定值。

例如:

我的要求是

sum of A = 8

所以我可以选择

1st row from table 1, 
2nd row from table 2,
3rd row from table 3.

或要求:

sum of G = 8

然后我选择

1st row from table 1,
4th row from table 3.

或者要求是

sum of C = 7 and sum of A = 8

我可以拥有

2nd row from table 1,
1st row from table 2,
1st row from table 3.

这是我的案例的简化版本。在我的数据库中,属性(上表中的A-G)可以多达150个,所选属性可以从1到6个不等,每个属性的目标值通常为10、15和20。很大,只有 1 到 4 个属性具有非零值。另外,我有 5 个这样的表。

当然,选择满足要求的条目的方式可以有多种版本。例如,当我给出要求时:

"sum of C = 7"

我可以选择

4th row from table 1,
3rd row from table 2,
2nd row from table 3;

虽然我也可以

1st row from table 1,
1st row from table 2,
2nd row from table 3;

那么我可以通过一些高级的sql查询技术来实现这个功能吗?

最佳答案

首先看到,我告诉你你没有正确满足你的要求。没问题,在另一个线程中你可以分享你的真正问题,导致你找到这个解决方案。有几个原因需要考虑它。

其次,我现在必须使用游标,我对您的要求越有信心,查询就会写得越好。

首先,您使用各种示例数据尝试我的脚本,并告诉我哪个输出是错误的。

declare @table1 table(A int,B int,C int,D int,E int,F int,G int)
insert into @table1 values      
(2, 0,1  , 3 , 0,0, 2)
,(0, 2,-1 , 0 , 0,1, 0)
,(4, 0,0  , 2 , 1,0, 0)
,(0, 0,3  , 0 , 2,0, 5)

declare @table2 table(A int,B int,C int,D int,E int,F int,G int)
insert into @table2 values  
(-1,   2,   3 ,   3 ,  0 ,   4,    0)
,(3 ,   0,   0 ,   2 ,  0 ,   0,    1)
,(1 ,   0,   1 ,   -2,  1 ,   3,    0)
,(0 ,   2,   -3,   0 ,  3 ,   0,    0)

declare @table3 table(A int,B int,C int,D int,E int,F int,G int)
insert into @table3 values  
(0,4  ,  5  ,  -1 ,  0 ,   2 ,   0)
,(0,-2 ,  3  ,  0  ,  0 ,   0 ,  -4)
,(3,0  ,  0  ,  -4 ,  1 ,   3 ,   0)
,(1,0  ,  -1 ,  5  ,  2 ,   0 ,   6)

DECLARE @ColNum int=3
declare @ReqSum int=7
DECLARE @Table1Number INT=0,@Table2Number int=0,@Table3Number int=0
DECLARE @i int=0,@j int=0,@k int=0
declare @t table(Table1Row int,Table2Row int,Table3Row int)
Declare @Exit bit=0

DECLARE @getTable1Number  CURSOR
SET @getTable1Number = CURSOR FOR

SELECT case when @ColNum=1 then A 
            when @ColNum=2 then B
            when @ColNum=3 then C
            when @ColNum=4 then D
            when @ColNum=5 then E
            when @ColNum=6 then F
            when @ColNum=7 then G
end
FROM @table1
OPEN @getTable1Number
FETCH NEXT
FROM @getTable1Number INTO @Table1Number
WHILE(@i<(Select count(*) from @table1)) 
BEGIN
set @i=@i+1
print 'i :'+cast(@i as varchar)
Set @j=0
set @k=0
set @Table2Number=0
 set @Table3Number=0
if(@Table1Number+@Table2Number+@Table3Number=@ReqSum)
Begin
insert into @t (Table1Row ,Table2Row ,Table3Row )VALUES(@i,@j,@k)

        set @Exit=1
    BREAK;
End
if(@Exit=1)
BREAK;
----------Declare @Table2 cursor here
DECLARE @getTable2Number  CURSOR
SET @getTable2Number = CURSOR FOR
SELECT case when @ColNum=1 then A 
            when @ColNum=2 then B
            when @ColNum=3 then C
            when @ColNum=4 then D
            when @ColNum=5 then E
            when @ColNum=6 then F
            when @ColNum=7 then G
END
FROM @table2
OPEN @getTable2Number
FETCH NEXT
FROM @getTable2Number INTO @Table2Number
WHILE (@j<(Select count(*) from @table2)) 
BEGIN

set @j=@j+1

set @k=0
print 'j :'+cast(@j as varchar)
set @Table3Number=0
if(@Table1Number+@Table2Number+@Table3Number=@ReqSum)
Begin
insert into @t (Table1Row ,Table2Row ,Table3Row )VALUES(@i,@j,@k)

        set @Exit=1
    BREAK;
End

if(@Exit=1)
BREAK;
----------Declare @Table3 cursor here
DECLARE @getTable3Number  CURSOR
SET @getTable3Number = CURSOR FOR
SELECT case when @ColNum=1 then A 
            when @ColNum=2 then B
            when @ColNum=3 then C
            when @ColNum=4 then D
            when @ColNum=5 then E
            when @ColNum=6 then F
            when @ColNum=7 then G
END
FROM @table3
OPEN @getTable3Number
FETCH NEXT
FROM @getTable3Number INTO @Table3Number
WHILE (@k<(Select count(*) from @table3)) 
BEGIN
set @k=@k+1
print 'k :'+cast(@k as varchar)
if(@Table1Number+@Table2Number+@Table3Number=@ReqSum)
Begin
insert into @t (Table1Row ,Table2Row ,Table3Row )VALUES(@i,@j,@k)

        set @Exit=1
    BREAK;
End

FETCH NEXT
FROM @getTable3Number INTO @Table3Number
END
CLOSE @getTable3Number
DEALLOCATE @getTable3Number
------ End @Table3 cursor
FETCH NEXT
FROM @getTable2Number INTO @Table2Number
END

CLOSE @getTable2Number
DEALLOCATE @getTable2Number
------ End @Table2 cursor

FETCH NEXT
FROM @getTable1Number INTO @Table1Number
END

CLOSE @getTable1Number
DEALLOCATE @getTable1Number

select * from @t

这里明白了, DECLARE @ColNum int=3 -- 您必须传递要求和的列的序号。(1=A,2=B,3=C 等) 声明 @ReqSum int=7 例如 sum ofA=8 意味着传递 @ColNum=1 和 @ReqSum=8

输出表为:declare @t table(Table1Row int,Table2Row int,Table3Row int) 假设返回上述输入

Table1Row   Table2Row   Table3Row
1                 2       3 

       Which means 1 rows from table1
                   2nd rows from table2
                   3rd rows from table3

关于mysql - 如何从多个表中选择一个(或零个)条目,并将这些值添加在一起以匹配特定值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40416293/

相关文章:

php - 验证失败,即使密码正确,使用 bcrypt 哈希方法

mysql - 设置密码后无法登录PhpMyAdmin EasyPHP

mysql - .Net用户登录程序

sql-server - 将多行数据移动到它自己的列中

sql-server - 有没有办法使用普通 ADO 从 SQL Server 检索 View 定义?

c# - SQL Server 查询 : Get a List of Columns Which Don't Exist in Another Table's Field

c - 实现 atoi - 递增变量 j 时出现段错误

python - 最接近零的两个产品之间的差异 : non brute-force solution?

algorithm - 检测矩形(按钮)是否在 x 或 y 轴上重叠

mysql - Sqoop 从 MySQL 导入 : Decimals always imported into Hive as String