sql >> Database >  >> RDS >> Mysql

Unieke gebruikers vinden uit gekoppelde waarden

Wilde inspringen met de optie om uw taak op te lossen met pure BigQuery (standaard SQL)

Vereisten/aannames :brongegevens bevinden zich in sandbox.temp.id1_id2_pairs
U moet dit vervangen door uw eigen of als u wilt testen met dummy-gegevens van uw vraag - u kunt deze tabel maken zoals hieronder (vervang natuurlijk sandbox.temp met uw eigen project.dataset )


Zorg ervoor dat u de respectievelijke bestemmingstabel instelt

Opmerking :je kunt alle respectievelijke zoekopdrachten (als tekst) onderaan dit antwoord vinden, maar voor nu illustreer ik mijn antwoord met screenshots - zodat alles wordt gepresenteerd - vraag, resultaat en gebruikte opties

Er zijn dus drie stappen:

Stap 1 - Initialisatie

Hier doen we gewoon de eerste groepering van id1 op basis van verbindingen met id2:

Zoals je hier kunt zien, hebben we een lijst gemaakt met alle id1-waarden met respectieve verbindingen op basis van een eenvoudige verbinding op één niveau via id2

Uitvoertabel is sandbox.temp.groups

Stap 2 - Iteraties groeperen

In elke iteratie zullen we groepering verrijken op basis van reeds bestaande groepen.
Bron van query is uitvoertabel van vorige stap (sandbox.temp.groups ) en Bestemming is dezelfde tabel (sandbox.temp.groups ) met Overschrijven

We zullen doorgaan met iteraties tot wanneer het aantal gevonden groepen hetzelfde zal zijn als in de vorige iteratie

Opmerking :u kunt gewoon twee BigQuery Web UI-tabbladen openen (zoals hierboven wordt weergegeven) en zonder enige code te wijzigen, hoeft u alleen maar Grouping uit te voeren en vervolgens keer op keer te controleren totdat iteratie convergeert

(voor specifieke gegevens die ik heb gebruikt in het gedeelte met vereisten - ik had drie iteraties - de eerste iteratie produceerde 5 gebruikers, de tweede iteratie produceerde 3 gebruikers en de derde iteratie produceerde opnieuw 3 gebruikers - wat aangaf dat we klaar waren met iteraties.

Natuurlijk, in het echte leven - het aantal iteraties kan meer zijn dan slechts drie - dus we hebben een soort automatisering nodig (zie de respectievelijke sectie onderaan het antwoord).

Stap 3 – Definitieve groepering
Als de id1-groepering is voltooid, kunnen we de definitieve groepering voor id2 toevoegen

Het eindresultaat staat nu in sandbox.temp.users tafel

Gebruikte zoekopdrachten (vergeet niet om de respectievelijke bestemmingstabellen in te stellen en indien nodig te overschrijven volgens de hierboven beschreven logica en screenshots):

Vereisten:

#standardSQL
SELECT 1 id, 'e1' id1, 'm1' id2 UNION ALL
SELECT 2,    'e1',     'm2' UNION ALL
SELECT 3,    'e2',     'm2' UNION ALL
SELECT 4,    'e3',     'm1' UNION ALL
SELECT 5,    'e4',     'm3' UNION ALL
SELECT 6,    'e5',     'm3' UNION ALL
SELECT 7,    'e5',     'm4' UNION ALL
SELECT 8,    'e4',     'm5' UNION ALL
SELECT 9,    'e6',     'm6' UNION ALL
SELECT 9,    'e7',     'm7' UNION ALL
SELECT 9,    'e2',     'm6' UNION ALL
SELECT 888,  'e4',     'm55'   

Stap 1

#standardSQL
WITH `yourTable` AS (select * from `sandbox.temp.id1_id2_pairs`
), x1 AS (SELECT id1, STRING_AGG(id2) id2s FROM `yourTable` GROUP BY id1
), x2 AS (SELECT id2, STRING_AGG(id1) id1s FROM `yourTable` GROUP BY id2 
), x3 AS (
  SELECT id, (SELECT STRING_AGG(i ORDER BY i) FROM (
    SELECT DISTINCT i FROM UNNEST(SPLIT(id1s)) i)) grp
  FROM (
    SELECT x1.id1 id, STRING_AGG((id1s)) id1s FROM x1 CROSS JOIN x2
    WHERE EXISTS (SELECT y FROM UNNEST(SPLIT(id1s)) y WHERE x1.id1 = y)
    GROUP BY id1) 
)
SELECT * FROM x3 

Stap 2 - Groeperen

#standardSQL
WITH x3 AS (select * from `sandbox.temp.groups`)
SELECT id, (SELECT STRING_AGG(i ORDER BY i) FROM (
  SELECT DISTINCT i FROM UNNEST(SPLIT(grp)) i)) grp
FROM (
  SELECT a.id, STRING_AGG(b.grp) grp FROM x3 a CROSS JOIN x3 b 
  WHERE EXISTS (SELECT y FROM UNNEST(SPLIT(b.grp)) y WHERE a.id = y)
  GROUP BY a.id )   

Stap 2 - Controleer

#standardSQL
SELECT COUNT(DISTINCT grp) users FROM `sandbox.temp.groups` 

Stap 3

#standardSQL
WITH `yourTable` AS (select * from `sandbox.temp.id1_id2_pairs`
), x1 AS (SELECT id1, STRING_AGG(id2) id2s FROM `yourTable` GROUP BY id1 
), x3 as (select * from `sandbox.temp.groups`
), f  AS (SELECT DISTINCT grp FROM x3 ORDER BY grp
)
SELECT ROW_NUMBER() OVER() id, grp id1, 
  (SELECT STRING_AGG(i ORDER BY i) FROM (SELECT DISTINCT i FROM UNNEST(SPLIT(id2)) i)) id2
FROM (
  SELECT grp, STRING_AGG(id2s) id2 FROM f 
  CROSS JOIN x1 WHERE EXISTS (SELECT y FROM UNNEST(SPLIT(f.grp)) y WHERE id1 = y)
  GROUP BY grp)

Automatisering :
Natuurlijk kan het bovenstaande "proces" handmatig worden uitgevoerd in het geval dat iteraties snel convergeren - je krijgt dus 10-20 runs. Maar in meer praktijkgevallen kunt u dit eenvoudig automatiseren met elke client naar keuze




  1. Stel de standaardoptie in in de vervolgkeuzelijst php en bewaar deze wanneer de vraag wordt ingediend

  2. Relationele databases

  3. Een DB-koppeling maken tussen twee Oracle-instanties

  4. Php-sessie en postproblemen op de inlogpagina