Как я могу выбрать одну (или ноль) запись из нескольких таблиц и добавить эти значения вместе, чтобы соответствовать определенному значению?

Здесь я поясню. Теперь предположим, что у меня есть 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) равна определенным значениям, которые я указываю.

Например:

Мое требование

сумма A = 8

Так что я могу выбрать

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

Или требование:

сумма G = 8

затем я выбираю

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

Или требование

сумма C = 7 и сумма 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 таких столов.

Конечно, способ выбора записей, удовлетворяющих требованию, может иметь много версий. Например, когда я даю требование:

«сумма 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-запросов?

1 ответ

  1. Видите ли, во-первых, я говорил, что вы не покрыли свое требование должным образом .нет проблем, в другом потоке вы можете поделиться своей реальной проблемой, которая приведет вас к этому решению.Есть несколько причин задуматься об этом.

    Во-вторых,я должен был использовать курсор сейчас,чем больше я уверен в вашем требовании ,лучше будет написан запрос.

    Сначала вы пробуете мой сценарий с различными образцами данных и говорите мне, какие выходные данные неверны.

    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 — необходимо передать порядковый номер столбца, для которого требуется sum.(1=A,2=B,3=c etc)
    declare @ReqSum int=7
    так, например sum ofA=8, что означает pass @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