Android-решение (Kotlin):
// 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()
}
}
}
Вероятно, не самый дешевый способ сделать это:
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
Вы видите, в основном я создаю новый набор результатов для каждого представления одного значения для множества значений каждого идентификатора в каждой таблице и присоединении только там, где они соответствуют.
Это более эффективно (это использует 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
Следующий запрос дает Вам требуемые результаты:
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)
Я добавил несколько дополнительных тестовых сценариев. Можно изменить обработку дубликата путем изменения способа, которым Вы используете отличные ключевые слова в своих агрегатах. В основном я получаю количество соответствий и сравниваю его с количеством необходимых соответствий в каждом @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
Как я запрашиваю для всех значений в @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
Работы для Вашего примера, и я думаю, что он будет работать на все случаи, но я не протестировал его полностью:
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
-- 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) я предполагаю, что у Вас нет дублирующегося идентификатора
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
Выполнить итерации точки далее:
select a.*
from @a a
inner join @b b on a.value = b.value
Это возвратит все значения в @a то соответствие @b
Несколько способов сделать это, но простое должно создать представление объединения как
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, но они могут решить много щекотливых вопросов, которые иначе требуют процессуального кодекса
При попытке возвратить только полные наборы записей, Вы могли бы попробовать это. Я определенно рекомендовал бы использовать значимые псевдонимы, хотя...
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
)
Как 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