Kami memecahkan masalah logis untuk siswa dalam SQL

Semuanya dimulai dengan layar berikutnya di grup whatsap dengan konten berikut (aslinya tidak dalam bahasa Rusia, tetapi tidak masalah):

Jumlah usia Sasha, Petit dan Viti adalah 67 tahun. Ketika Victor pada usia Sasha, masih ada 3 tahun lagi sebelum kelahiran Petit. Berapa jumlah usia Sasha dan Petit?

Jelas bahwa tugas ini untuk anak sekolah, tetapi setelah berjam-jam memecahkan masalah SQL-EX (omong-omong, terima kasih lebih banyak kepada mereka untuk tugas-tugas berkualitas tinggi dan menarik), hal pertama yang terlintas dalam pikiran adalah:

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 

Di mana tab adalah tablet dengan garis 100. Solusi: 32, yang dijawab kolega dalam grup: "Dan berapa individu?" Kami menghapus DISTINCT dan mengubah "+" ke "," ... ternyata 31 pasang opsi ... bukan jawaban yang tepat. Untuk beberapa alasan saya ingin menjawab dengan pasti, dan memiliki setidaknya beberapa bukti di tangan.

Jadi Kami mengambil semua klien yang tersedia dalam database dengan nama-nama dari tugas dan ulang tahun mereka:

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

Dalam aslinya, namanya berbeda, jelas bahwa database berisi nama sesuai dengan paspor.
Kami terhubung tiga kali dan menambahkan kondisi bahwa jumlah usia Sasha dan Petya adalah 32 ketika Vita berusia 35:

 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 

tetapi saya tidak berpikir untuk menghitung jumlah klien di muka, dan, ternyata, sangat sia-sia. Tentu saja, ada banyak dari mereka, dan mengalikan semua satu sama lain, meskipun ada beberapa kondisi, seseorang dapat menunggu hasilnya selamanya. Entah bagaimana Anda perlu mengurangi jumlah baris, katakanlah kita hanya menyisakan senama. Setelah menambahkan persyaratan, jumlah opsi yang memungkinkan ternyata sekitar setengah juta. Juga, kondisi ditambahkan bahwa usia tidak boleh negatif, dan ada beberapa kebingungan dengan tanggal lahir pada hari yang sama, jadi saya sedikit mengoreksi akurasinya. Tetapi masih ada banyak hasil.

Sudah berhenti berlangganan di grup bahwa ia mencoba membuktikan sesuatu, tetapi tidak ada yang berhasil. Salah satu rekan menyarankan hanya mencari klien dengan patronimik langka. Ini tidak lagi sesuai dengan kondisi masalah, tetapi melemparkan pemikiran berikut.

Mengapa karakter dari tugas ini bukan saudara? Yaitu bukan fakta bahwa itu adalah saudara-saudara, kami tidak dapat memverifikasi ini, tetapi senama dengan patronimik yang sama - ini mudah. Mungkin tidak ada dalam database, itu sedikit menakutkan, tetapi setelah menambahkan kondisinya, permintaan masih mengeluarkan 13.000 opsi yang memungkinkan.

Menyadari bahwa saya membuang-buang waktu untuk semua jenis omong kosong yang tidak berguna, sebelum saya meninggalkan semuanya, saya memutuskan untuk memeriksa nama belakang dan patronimik saya. Dan ini dia, dengan nama keluarga tidak ada masalah, tetapi alih-alih nama tengah pada halaman tak berujung sampel ada tanda hubung. Yaitu permintaan pada dasarnya hanya menyisakan pelanggan yang nama tengahnya tidak dikenal. Dengan hanya menambahkan kondisi terakhir, saya hanya mendapat 3 entri. Layar ini dengan kata-kata "tidak mungkin bahwa tugas itu dirumuskan pada tahun 50-an, dan jika Anda hanya meninggalkan tahun 2001, maka para Bruder berusia 35, 3, 29"

Tentu saja, semua ini sangat sewenang-wenang, dan demi lelucon, tidak perlu menganggap semuanya serius. Bersenang-senang, kami adalah programmer ...

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


All Articles