Resolvemos um problema lógico para estudantes em SQL

Tudo começou com a próxima tela no grupo whatsap com o seguinte conteúdo (o original não está em russo, mas não importa):

A soma das idades de Sasha, Petit e Viti é de 67 anos. Quando Victor tinha a idade de Sasha, restaram mais três anos antes do nascimento de Petit. Qual é a soma das idades de Sasha e Petit?

É claro que a tarefa é para crianças em idade escolar, mas após longas horas de solução de problemas do SQL-EX (a propósito, obrigado mais por tarefas interessantes e de alta qualidade), a primeira coisa que vem à mente é:

SELECT DISTINCT r2 + r3 FROM (SELECT rownum r1 FROM tab) r1 CROSS JOIN (SELECT rownum r2 FROM tab) r2 CROSS JOIN (SELECT rownum r3 FROM tab) r3 WHERE r1 + r2 + r3 = 67 AND r1 - r2 = r3 + 3 

Onde tab é qualquer tablet com cerca de 100 linhas Solução: 32, à qual o colega do grupo respondeu: "E quantos individualmente?" Removemos DISTINCT e alteramos "+" para "," ... resultam 31 pares de opções ... não é uma resposta exata. Por alguma razão, eu queria responder com certeza e ter pelo menos algumas evidências à mão.

Então Levamos todos os clientes disponíveis no banco de dados à mão com os nomes da tarefa e seus aniversários:

 WITH t AS (SELECT DISTINCT upper(NAME) NAME, to_date(birthdate, 'RRRRMMDD') dob FROM clients WHERE upper(NAME) IN ('', '', '')) 

No original, os nomes são diferentes, é claro que o banco de dados contém nomes de acordo com o passaporte.
Nós nos conectamos três vezes e adicionamos as condições em que a soma das idades de Sasha e Petya é 32 quando Vita tem 35 anos:

 SELECT v.dob vitya, --   ,    s.dob sasha, p.dob petya, add_months(v.dob, 35 * 12) data_zadachi --    ) FROM tv CROSS JOIN ts CROSS JOIN tp WHERE v.name = '' AND s.name = '' AND p.name = '' AND trunc((add_months(v.dob, 35 * 12) - s.dob) / 365.24) + trunc((add_months(v.dob, 35 * 12) - p.dob) / 365.24) = 32 

mas não pensei em calcular o número de clientes com antecedência e, como se viu, muito vaidoso. É claro que havia muitos deles e, multiplicando-se um pelo outro, apesar de algumas condições, era possível esperar o resultado para sempre. De alguma forma, você precisa reduzir o número de linhas, digamos que deixamos apenas nomes. Depois de adicionar as condições, o número de opções possíveis ficou em cerca de meio milhão. Além disso, foram adicionadas condições de que a idade não pode ser negativa, e houve alguma confusão com as datas de nascimento no mesmo dia, então eu corrigi levemente a precisão. Mas ainda havia muitos resultados.

Já não inscrito no grupo, ele estava tentando provar alguma coisa, mas nada resultou. Um dos colegas sugeriu procurar apenas clientes com um raro patronímico. Isso não se adequava mais às condições do problema, mas jogava o seguinte pensamento.

Por que os personagens da tarefa não são irmãos? I.e. não é o fato de serem os irmãos, não podemos verificar isso, mas os nomes com o mesmo patronímico - isso é fácil. Talvez não haja nenhum no banco de dados, foi um pouco assustador, mas depois de adicionar a condição, a solicitação ainda emitiu 13.000 opções possíveis.

Percebendo que estava desperdiçando meu tempo com todo tipo de bobagem inútil, antes de deixar tudo, decidi checar meus sobrenomes e nomes patronímicos. E aqui está, com sobrenomes não há problemas, mas em vez de um nome do meio nas infinitas páginas da amostra, havia traços. I.e. a solicitação basicamente deixou apenas os clientes cujos nomes do meio não eram conhecidos. Simplesmente adicionando a última condição, obtive apenas 3 entradas. Essa tela com as palavras “é improvável que a tarefa tenha sido formulada nos anos 50, e se você deixar apenas 2001, então os irmãos terão 35, 3, 29”

Obviamente, tudo isso é muito arbitrário e, por brincadeira, não é necessário levar tudo a sério. Se divertindo, nós somos programadores ...

Source: https://habr.com/ru/post/pt423871/


All Articles