Saya mempunyai beberapa pengiraan dan ingin melakukan ini dalam pertanyaan.
Terdapat ibu bapa dan anakmeja dengan hubungan satu dengan ramai:
CREATE TABLE `parent` ( `id` int NOT NULL AUTO_INCREMENT, `value` decimal(10,2) DEFAULT NULL, PRIMARY KEY (`id`) );
CREATE TABLE `children` ( `id` int NOT NULL AUTO_INCREMENT, `parent_id` int NOT NULL, `multiple` decimal(10,2) DEFAULT NULL, `sum` decimal(10,2) DEFAULT NULL, PRIMARY KEY (`id`), CONSTRAINT `fk_parent` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`) );
Untuk mencari nilai akhir ibu bapa, saya harus mengulangi anak-anak dan mengira formula berikut:
newParentValue = childMultiple(parentValue + childSum)
Perlaksanaan dalam kod adalah seperti berikut:
function calculateFinalParentValue($parentValue, $children) { foreach ($children as $child) { $parentValue = $child['multiple'] * ($parentValue + $child['sum']); } return $parentValue; }
Bagaimana untuk melaksanakan pengiraan dalam pertanyaan?
Saya cuba cara ini (menggunakan pembolehubah sementara):
set @value = 0; SELECT p.id, @value := (c.multiple * (@value + c.sum)) AS value FROM parent p JOIN children c ON p.id = c.parent_id AND @value := p.value;
Saya tetapkan pembolehubah dalam keadaan gabungan (@value := p.value)
untuk menetapkan semula pembolehubah bagi setiap ibu bapa baharu.
Pertanyaan ini mengembalikan baris untuk setiap ibu bapa bersama dengan bilangan anak, saya memerlukan baris terakhir dalam setiap sambungan ibu bapa sebagai jawapannya.
Tetapi cara ini tidak mampan Adakah cara yang lebih baik?
Contoh:
mysql> select * from parent; +----+-------+ | id | value | +----+-------+ | 1 | 10.00 | | 2 | 20.00 | +----+-------+ mysql> select * from children; +----+-----------+----------+------+ | id | parent_id | multiple | sum | +----+-----------+----------+------+ | 1 | 1 | 1.00 | 1.00 | | 2 | 1 | 1.00 | 1.00 | | 3 | 1 | 1.00 | 1.00 | | 4 | 2 | 2.00 | 2.00 | | 5 | 2 | 2.00 | 2.00 | +----+-----------+----------+------+
Berdasarkan data di atas, saya menjangkakan jawapan berikut:
+----+--------+ | id | value | +----+--------+ | 1 | 11.00 | | 1 | 12.00 | | 1 | 13.00 | <- final value for parant.id = 1 | 2 | 44.00 | | 2 | 92.00 | <- final value for parant.id = 2 +----+--------+
Untuk parent.id=1, terdapat tiga anak dan parent.value ialah 10, jadi selepas mengira formula untuk anak pertama, nilai baharu ialah 1 * (10 + 1) = 11
,第二个孩子的值是 1 * (11 + 1) = 12
正如预期的那样,第三个子值是 1 * (12 + 1) = 13
(iaitu gandaan dalam ketiga-tiga kanak-kanak dan jumlahnya bersamaan 1).
Untuk parent.id=2, terdapat dua anak dan parent.value ialah 20, jadi selepas mengira formula untuk anak pertama, nilai baharu ialah 2 * (20 + 2) = 44
,第二个孩子的值是 2 * (44 + 2) = 92
(kedua-dua kanak-kanak ialah gandaan dan jumlahnya bersamaan 2).
Pada akhirnya saya hanya mahukan nilai akhir setiap ibu bapa, jadi hasil jangkaan akhir saya ialah:
+----+--------+ | id | value | +----+--------+ | 1 | 13.00 | | 2 | 92.00 | +----+--------+
Hanya untuk memudahkan contoh, semua multiply
和 sum
lajur setiap jadual anak ibu bapa adalah sama (dengan mengandaikan nilai yang berbeza) dan nilai akhir ialah maksimum, nilai akhir mungkin tidak maksimum setiap kali. < /p>
Gunakan
ROW_NUMBER()
窗口函数对children
的行进行排名,按parent_id
分区并按id
和SUM()
fungsi tetingkap untuk menyusun untuk mendapatkan jumlah yang dikehendaki.Akhir sekali gunakan fungsi tetingkap
FIRST_VALUE()
untuk mendapatkan jumlah terakhir bagi setiap id:Lihat Demo.
Sedikit rumit kerana anda perlu menetapkan semula nilai anda di tengah apabila ibu bapa berubah.
Cuba pertanyaan berikut:
Anda juga boleh menggunakan
IF
语句替换上述提到的CASE
pernyataan (lebih mudah dibaca)Ini sepatutnya memberi anda output yang diingini.
Saya menggunakan dua pembolehubah
@current_parent_value
和@running_parent
@running_parent
将帮助你确定前一行和当前行是否属于同一个parent
,而@current_parent_value
akan membantu anda menyimpan nilai semasa.