Bigquery SQL-код для получения самого раннего контакта - PullRequest
0 голосов
/ 13 сентября 2018

У меня есть копия наших данных о продажах в bigquery, я пытаюсь соединить таблицу контактов с таблицей счетов.

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

Сегодня я ходил по кругу, гуглял и пытался объединить запрос, но все дороги либо приводят к отсутствию учетных записей, ни к одной учетной записи, ни к множеству контактов на учетную запись (игнорируя самое раннее требование).

Вот последний запрос. это не дает никаких результатов. Я думаю, что я почти там, но все еще борюсь. любая помощь будет наиболее ценной.


SELECT distinct  
 c.accountid as Acct_id 
,a.id as a_Acct_ID
,c.id as Cont_ID
,a.id AS a_CONT_ID 
,c.email
,c.createddate

FROM `sfdcaccounttable` a

INNER JOIN `sfdccontacttable` c
ON c.accountid = a.id

INNER JOIN
    (SELECT a2.id, c2.accountid, c2.createddate AS MINCREATEDDATE
    FROM `sfdccontacttable` c2

    INNER JOIN `sfdcaccounttable` a2 ON a2.id = c2.accountid

 GROUP BY 1,2,3
 ORDER BY c2.createddate asc LIMIT 1) c3 
ON c.id = c3.id

ORDER BY a.id asc

LIMIT 10

Ответы [ 2 ]

0 голосов
/ 14 сентября 2018

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

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

По сути, вам нужно создать таблицу меньшего размера (еще лучше сделать ее представлением) с идентификатором, и это будет первая транзакция. Это похоже на то, что вы поделили немного по-другому, поскольку вам нужно сгруппировать ТОЛЬКО в самом верхнем запросе.

Это выглядит примерно так

select 
# contact ids that are first time contacts
b.id as cont_id,
b.accountid

from `sfdccontacttable` as b inner join 
(   select accountid,
    min(createddate) as first_tx_time
    FROM `sfdccontacttable`  
    group by 1) as a on (a.accountid = b.accountid and b.createddate = a.first_tx_time)
group by 1, 2

Вам необходимо сделать это таким образом, потому что в противном случае вы можете получить несколько идентификаторов для каждой учетной записи (если с этим связаны другие измерения). Таким образом, это своего рода перспектива на будущее, поскольку вы можете добавить несколько измерений в базовые таблицы, не влияя на результат, а также вы можете использовать предложение where во внутреннем запросе, чтобы определить «действительный» контакт и так далее. Затем вы можете сохранить его как представление и просто сослаться на него в любом подзапросе или операции соединения

0 голосов
/ 13 сентября 2018

Настройка представления / подзапроса для client_first или client_last

как:

SELECT * except(_rank) from (
  select rank() over (partition by accountid order by createddate  ASC) as _rank, 
   * 
   FROM `prj.dataset.sfdccontacttable`  
)  where _rank=1

в основном он использует оконную функцию для нумерации строк и возврата первой строки, используя ASC, который является первым клиентом, используя DESC, который является последней записью клиента.

Вы можете сделать то же самое для accounts, затем вы можете присоединиться к двум простым, так как ровно 1 запись будет для каждой сущности.

UPDATE

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

#standardSQL
SELECT e.* FROM (
  SELECT ARRAY_AGG(
    t ORDER BY t.createddate ASC LIMIT 1
  )[OFFSET(0)]  e
  FROM `dataset.sfdccontacttable` t 
  GROUP BY t.accountid 
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...