T-SQL: Как я получаю строки от одной таблицы, значения которой полностью совпадают со значениями в другой таблице?

Android-решение (Kotlin):

  1. Вам нужно FirebaseOptions BUILDER (!) для установки api-ключа, db-url и т. д., и не забудьте вызвать build () в конце
  2. Сделайте вторичную переменную auth, вызвав FirebaseApp.initializeApp ()
  3. Получите экземпляр FirebaseAuth, передав вновь созданный вторичный auth и сделайте все, что хотите (например, createUser)
    // 1. you can find these in your project settings under general tab
    val firebaseOptionsBuilder = FirebaseOptions.Builder()
    firebaseOptionsBuilder.setApiKey("YOUR_API_KEY")
    firebaseOptionsBuilder.setDatabaseUrl("YOUR_DATABASE_URL")
    firebaseOptionsBuilder.setProjectId("YOUR_PROJECT_ID")
    firebaseOptionsBuilder.setApplicationId("YOUR_APPLICATION_ID") //not sure if this one is needed
    val firebaseOptions = firebaseOptionsBuilder.build()
    
    // indeterminate progress dialog *ANKO*
    val progressDialog = indeterminateProgressDialog(resources.getString(R.string.progressDialog_message_registering))
    progressDialog.show()
    
    // 2. second auth created by passing the context, firebase options and a string for secondary db name
    val newAuth = FirebaseApp.initializeApp(this@ListActivity, firebaseOptions, Constants.secondary_db_auth)
    // 3. calling the create method on our newly created auth, passed in getInstance
    FirebaseAuth.getInstance(newAuth).createUserWithEmailAndPassword(email!!, password!!)
            .addOnCompleteListener { it ->
    
                if (it.isSuccessful) {
    
                    // 'it' is a Task<AuthResult>, so we can get our newly created user from result
                    val newUser = it.result.user
    
                    // store wanted values on your user model, e.g. email, name, phonenumber, etc.
                    val user = User()
                    user.email = email
                    user.name = name
                    user.created = Date().time
                    user.active = true
                    user.phone = phone
    
                    // set user model on /db_root/users/uid_of_created_user/, or wherever you want depending on your structure
                    FirebaseDatabase.getInstance().reference.child(Constants.db_users).child(newUser.uid).setValue(user)
    
                    // send newly created user email verification link
                    newUser.sendEmailVerification()
    
                    progressDialog.dismiss()
    
                    // sign him out
                    FirebaseAuth.getInstance(newAuth).signOut()
                    // DELETE SECONDARY AUTH! thanks, Jimmy :D
                    newAuth.delete()
    
                } else {
    
                    progressDialog.dismiss()
    
                    try {
    
                        throw it.exception!!
    
                        // catch exception for already existing user (e-mail)
                    } catch (e: FirebaseAuthUserCollisionException) {
    
                        alert(resources.getString(R.string.exception_FirebaseAuthUserCollision), resources.getString(R.string.alertDialog_title_error)) {
    
                            okButton {
    
                                isCancelable = false
    
                            }
    
                        }.show()
    
                    }
    
                }
    
            }
    
5
задан Matt 4 December 2014 в 09:44
поделиться

12 ответов

Вероятно, не самый дешевый способ сделать это:

SELECT a.pkId,b.otherId FROM
    (SELECT a.pkId,CHECKSUM_AGG(DISTINCT a.value) as 'ValueHash' FROM @a a GROUP BY a.pkId) a
    INNER JOIN (SELECT b.otherId,CHECKSUM_AGG(DISTINCT b.value) as 'ValueHash' FROM @b b GROUP BY b.otherId) b
ON a.ValueHash = b.ValueHash

Вы видите, в основном я создаю новый набор результатов для каждого представления одного значения для множества значений каждого идентификатора в каждой таблице и присоединении только там, где они соответствуют.

6
ответ дан 18 December 2019 в 09:11
поделиться

Это более эффективно (это использует TOP 1 вместо COUNT), и работы с (-2, 1000):

SELECT  *
FROM    (
        SELECT  ab.pkid, ab.otherID,
                (
                SELECT  TOP 1 COALESCE(ai.value, bi.value)
                FROM    (
                        SELECT  *
                        FROM    @a aii
                        WHERE   aii.pkid = ab.pkid
                        ) ai
                FULL OUTER JOIN
                        (
                        SELECT  *
                        FROM    @b bii
                        WHERE   bii.otherID = ab.otherID
                        ) bi
                ON      ai.value = bi.value
                WHERE   ai.pkid IS NULL OR bi.otherID IS NULL
                ) unmatch
        FROM
                (
                SELECT  DISTINCT pkid, otherid
                FROM    @a a , @b b
                ) ab
        ) q
WHERE   unmatch IS NOT NULL
7
ответ дан 18 December 2019 в 09:11
поделиться

Следующий запрос дает Вам требуемые результаты:

select A.pkid, B.otherId
    from @a A, @b B 
    where A.value = B.value
    group by A.pkid, B.otherId
    having count(B.value) = (
        select count(*) from @b BB where B.otherId = BB.otherId)
2
ответ дан 18 December 2019 в 09:11
поделиться

Я добавил несколько дополнительных тестовых сценариев. Можно изменить обработку дубликата путем изменения способа, которым Вы используете отличные ключевые слова в своих агрегатах. В основном я получаю количество соответствий и сравниваю его с количеством необходимых соответствий в каждом @a и @b.

declare @a table
(
    pkid int,
    value int
)

declare @b table
(
    otherID int,
    value int
)


insert into @a values (1, 1000)
insert into @a values (1, 1001)

insert into @a values (2, 1000)
insert into @a values (2, 1001)
insert into @a values (2, 1002)

insert into @a values (3, 1000)
insert into @a values (3, 1001)
insert into @a values (3, 1001)

insert into @a values (4, 1000)
insert into @a values (4, 1000)
insert into @a values (4, 1001)


insert into @b values (-1, 1000)
insert into @b values (-1, 1001)
insert into @b values (-1, 1002)

insert into @b values (-2, 1001)
insert into @b values (-2, 1002)

insert into @b values (-3, 1000)
insert into @b values (-3, 1001)
insert into @b values (-3, 1001)



SELECT Matches.pkid, Matches.otherId
FROM
(
    SELECT a.pkid, b.otherId, n = COUNT(*)
    FROM @a a
    INNER JOIN @b b
        ON a.Value = b.Value
    GROUP BY a.pkid, b.otherId
) AS Matches

INNER JOIN 
(
    SELECT
        pkid,
        n = COUNT(DISTINCT value)
    FROM @a
    GROUP BY pkid
) AS ACount
ON Matches.pkid = ACount.pkid

INNER JOIN
(
    SELECT
        otherId,
        n = COUNT(DISTINCT value)
    FROM @b
    GROUP BY otherId
) AS BCount
    ON Matches.otherId = BCount.otherId

WHERE Matches.n = ACount.n AND Matches.n = BCount.n
1
ответ дан 18 December 2019 в 09:11
поделиться

Как я запрашиваю для всех значений в @a, которые полностью совпадают с @b?

Я боюсь, что это определение является не совсем совершенно четким. Кажется от Вашего дополнительного примера желанием всех пар a.pkid, b.otherID, для которого каждый b.value для данного b.otherID является также a.value для данного a.pkid.

Другими словами, Вы хотите pkids в @a, которые имеют по крайней мере все значения для otherIDs в b. Дополнительные значения в @a, кажется, хорошо. Снова, это рассуждает на основе Вашего дополнительного примера и предположения, которое (1,-2) и (2,-2) было бы допустимыми результатами. В обоих из тех случаев значения a.value для данного pkid являются больше, чем значения b.value для данного otherID.

Так, с этим в памяти:

    select
    matches.pkid
    ,matches.otherID
from
(
    select 
        a.pkid
        ,b.otherID
        ,count(1) as cnt
    from @a a
    inner join @b b
        on b.value = a.value
    group by 
        a.pkid
        ,b.otherID
) as matches
inner join
(
    select
        otherID
        ,count(1) as cnt
    from @b
    group by otherID
) as b_counts
on b_counts.otherID = matches.otherID
where matches.cnt = b_counts.cnt
1
ответ дан 18 December 2019 в 09:11
поделиться

Работы для Вашего примера, и я думаю, что он будет работать на все случаи, но я не протестировал его полностью:

SELECT
    SQ1.pkid
FROM
    (
        SELECT
            a.pkid, COUNT(*) AS cnt
        FROM
            @a AS a
        GROUP BY
            a.pkid
    ) SQ1
INNER JOIN
    (
        SELECT
            a1.pkid, b1.otherID, COUNT(*) AS cnt
        FROM
            @a AS a1
        INNER JOIN @b AS b1 ON b1.value = a1.value
        GROUP BY
            a1.pkid, b1.otherID
    ) SQ2 ON
        SQ2.pkid = SQ1.pkid AND
        SQ2.cnt = SQ1.cnt
INNER JOIN
    (
        SELECT
            b2.otherID, COUNT(*) AS cnt
        FROM
            @b AS b2
        GROUP BY
            b2.otherID
    ) SQ3 ON
        SQ3.otherID = SQ2.otherID AND
        SQ3.cnt = SQ1.cnt
1
ответ дан 18 December 2019 в 09:11
поделиться
-- Note, only works as long as no duplicate values are allowed in either table
DECLARE @validcomparisons TABLE (
    pkid    INT,
    otherid INT,
    num INT
)

INSERT INTO @validcomparisons (pkid, otherid, num)
SELECT  a.pkid, b.otherid, A.cnt
FROM    (select pkid, count(*) as cnt FROM @a group by pkid) a
INNER JOIN  (select otherid, count(*) as cnt from @b group by otherid) b 
    ON  b.cnt = a.cnt

DECLARE @comparison TABLE (
    pkid    INT,
    otherid INT,
    same    INT)

insert into @comparison(pkid, otherid, same)
SELECT a.pkid, b.otherid, count(*)
FROM    @a a
INNER JOIN  @b b
    ON  a.value = b.value
GROUP BY    a.pkid, b.otherid

SELECT  COMP.PKID, COMP.OTHERID
FROM    @comparison comp
INNER JOIN  @validcomparisons val
    ON  comp.pkid = val.pkid
    AND comp.otherid = val.otherid
    AND comp.same = val.num
1
ответ дан 18 December 2019 в 09:11
поделиться

1) я предполагаю, что у Вас нет дублирующегося идентификатора

2) получите ключ с тем же количеством значения

3) строка с количеством значения ключа, равного количеству равного значения, является целью

Я надеюсь, что это - то, что Вы искали (Вы не ищете производительность не так ли?)

declare @a table(    pkid int,    value int)
declare @b table(    otherID int,    value int)

insert into @a values (1, 1000)
insert into @a values (1, 1001)
insert into @a values (2, 1000)
insert into @a values (2, 1001)
insert into @a values (2, 1002)
insert into @a values (3, 1000)  
insert into @a values (3, 1001)
insert into @a values (4, 1000)
insert into @a values (4, 1001)
insert into @b values (-1, 1000)
insert into @b values (-1, 1001)
insert into @b values (-1, 1002)
insert into @b values (-2, 1001)
insert into @b values (-2, 1002)
insert into @b values (-3, 1000)
insert into @b values (-3, 1001)

  select cntok.cntid1 as cntid1, cntok.cntid2 as cntid2
  from
 (select cnt.cnt, cnt.cntid1, cnt.cntid2 from
    (select acnt.cnt as cnt, acnt.cntid as cntid1, bcnt.cntid as cntid2 from
          (select count(pkid) as cnt, pkid as cntid from @a group by pkid)
           as acnt
                full join 
               (select count(otherID) as cnt, otherID as cntid from @b group by otherID)
                as bcnt
                   on  acnt.cnt = bcnt.cnt)
     as cnt
     where cntid1 is not null and cntid2 is not null)
   as cntok 
inner join 
(select count(1) as cnt, cnta.cntid1 as cntid1, cnta.cntid2 as cntid2
from
    (select cnt, cntid1, cntid2, a.value as value1 
     from
         (select cnt.cnt, cnt.cntid1, cnt.cntid2 from
            (select acnt.cnt as cnt, acnt.cntid as cntid1, bcnt.cntid as cntid2 from
                  (select count(pkid) as cnt, pkid as cntid from @a group by pkid)
                   as acnt
                        full join 
                       (select count(otherID) as cnt, otherID as cntid from @b group by otherID)
                        as bcnt
                           on  acnt.cnt = bcnt.cnt)
             as cnt
             where cntid1 is not null and cntid2 is not null)
         as cntok 
             inner join @a as a on a.pkid = cntok.cntid1)
      as cnta
         inner join

             (select cnt, cntid1, cntid2, b.value as value2 
             from
             (select cnt.cnt, cnt.cntid1, cnt.cntid2 from
                    (select acnt.cnt as cnt, acnt.cntid as cntid1, bcnt.cntid as cntid2 from
                          (select count(pkid) as cnt, pkid as cntid from @a group by pkid)
                           as acnt
                                full join 
                               (select count(otherID) as cnt, otherID as cntid from @b group by otherID)
                                as bcnt
                                   on  acnt.cnt = bcnt.cnt)
                     as cnt
                     where cntid1 is not null and cntid2 is not null)
                 as cntok 
                     inner join @b as b on b.otherid = cntok.cntid2)
               as cntb
               on cnta.cntid1 = cntb.cntid1 and cnta.cntid2 = cntb.cntid2 and cnta.value1 = cntb.value2
      group by cnta.cntid1, cnta.cntid2) 
   as cntequals
   on cntok.cnt = cntequals.cnt and cntok.cntid1 = cntequals.cntid1 and cntok.cntid2 = cntequals.cntid2
0
ответ дан 18 December 2019 в 09:11
поделиться

Выполнить итерации точки далее:

select a.*
from @a a 
inner join @b b on a.value = b.value

Это возвратит все значения в @a то соответствие @b

0
ответ дан 18 December 2019 в 09:11
поделиться

Несколько способов сделать это, но простое должно создать представление объединения как

create view qryMyUinion as
select * from table1 
union all
select * from table2

старайтесь использовать объединение все, не простое объединение, поскольку это опустит дубликаты

затем сделайте это

select count( * ), [field list here] 
from qryMyUnion
group by [field list here]
having count( * ) > 1

операторы Union и Having имеют тенденцию быть наиболее пропущенной частью стандартного SQL, но они могут решить много щекотливых вопросов, которые иначе требуют процессуального кодекса

0
ответ дан 18 December 2019 в 09:11
поделиться

При попытке возвратить только полные наборы записей, Вы могли бы попробовать это. Я определенно рекомендовал бы использовать значимые псевдонимы, хотя...

Cervo является правильным, нам нужна дополнительная проверка, чтобы гарантировать что точного совпадения b и не надмножества b. Это - больше громоздкого решения в этой точке, таким образом, это только было бы разумно в контекстах, где аналитические функции в других решениях не работают.

select 
    a.pkid,
    a.value
from
    @a a
where
    a.pkid in
    (
    select
        pkid
    from
        (
        select 
            c.pkid,
            c.otherid,
            count(*) matching_count
        from 
            (
            select 
                a.pkid,
                a.value,
                b.otherid
            from 
                @a a inner join @b b 
                on a.value = b.value
            ) c
        group by 
            c.pkid,
            c.otherid
        ) d
        inner join
        (
        select 
            b.otherid,
            count(*) b_record_count
        from
            @b b
        group by
            b.otherid
        ) e
        on d.otherid = e.otherid
        and d.matching_count = e.b_record_count
        inner join
        (
        select 
            a.pkid match_pkid,
            count(*) a_record_count
        from
            @a a
        group by
            a.pkid
        ) f
        on d.pkid = f.match_pkid
        and d.matching_count = f.a_record_count
    )
0
ответ дан 18 December 2019 в 09:11
поделиться

Как CQ говорит, простое внутреннее объединение - все, в чем Вы нуждаетесь.

Select * -- all columns but only from #a
from #a 
inner join #b 
on #a.value = #b.value -- only return matching rows
where #a.pkid  = 2
-1
ответ дан 18 December 2019 в 09:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: