diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000000..2fc343b9c9600 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,20 @@ +# Use Node.js version 14 as the base image +FROM node:14 + +# Set the working directory inside the container +WORKDIR /app + +# Copy package.json and package-lock.json (if present) to the working directory +COPY package*.json ./ + +# Install npm dependencies +RUN npm install + +# Copy all files from the current directory to the working directory in the container +COPY . . + +# Expose port 80 to allow communication to/from the container +EXPOSE 80 + +# Specify the command to run the application +CMD ["npm", "start"] diff --git "a/lcof2/\345\211\221\346\214\207 Offer II 070. \346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\345\217\252\345\207\272\347\216\260\344\270\200\346\254\241\347\232\204\346\225\260\345\255\227/README.md" "b/lcof2/\345\211\221\346\214\207 Offer II 070. \346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\345\217\252\345\207\272\347\216\260\344\270\200\346\254\241\347\232\204\346\225\260\345\255\227/README.md" index fc9c626d119c5..a7e4f21e54570 100644 --- "a/lcof2/\345\211\221\346\214\207 Offer II 070. \346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\345\217\252\345\207\272\347\216\260\344\270\200\346\254\241\347\232\204\346\225\260\345\255\227/README.md" +++ "b/lcof2/\345\211\221\346\214\207 Offer II 070. \346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\345\217\252\345\207\272\347\216\260\344\270\200\346\254\241\347\232\204\346\225\260\345\255\227/README.md" @@ -158,7 +158,7 @@ class Solution { func singleNonDuplicate(_ nums: [Int]) -> Int { var left = 0 var right = nums.count - 1 - + while left < right { let mid = (left + right) / 2 if nums[mid] != nums[mid ^ 1] { @@ -167,7 +167,7 @@ class Solution { left = mid + 1 } } - + return nums[left] } } diff --git a/solution/0000-0099/0052.N-Queens II/README.md b/solution/0000-0099/0052.N-Queens II/README.md index f78b7ece53879..05c8e6663930e 100644 --- a/solution/0000-0099/0052.N-Queens II/README.md +++ b/solution/0000-0099/0052.N-Queens II/README.md @@ -220,6 +220,34 @@ function totalNQueens(n: number): number { } ``` +#### JavaScript + +```js +function totalNQueens(n) { + const cols = Array(10).fill(false); + const dg = Array(20).fill(false); + const udg = Array(20).fill(false); + let ans = 0; + const dfs = i => { + if (i === n) { + ++ans; + return; + } + for (let j = 0; j < n; ++j) { + let [a, b] = [i + j, i - j + n]; + if (cols[j] || dg[a] || udg[b]) { + continue; + } + cols[j] = dg[a] = udg[b] = true; + dfs(i + 1); + cols[j] = dg[a] = udg[b] = false; + } + }; + dfs(0); + return ans; +} +``` + #### C# ```cs diff --git a/solution/0000-0099/0052.N-Queens II/README_EN.md b/solution/0000-0099/0052.N-Queens II/README_EN.md index 58e24c33a6dfb..de246c3a2745d 100644 --- a/solution/0000-0099/0052.N-Queens II/README_EN.md +++ b/solution/0000-0099/0052.N-Queens II/README_EN.md @@ -214,6 +214,34 @@ function totalNQueens(n: number): number { } ``` +#### JavaScript + +```js +function totalNQueens(n) { + const cols = Array(10).fill(false); + const dg = Array(20).fill(false); + const udg = Array(20).fill(false); + let ans = 0; + const dfs = i => { + if (i === n) { + ++ans; + return; + } + for (let j = 0; j < n; ++j) { + let [a, b] = [i + j, i - j + n]; + if (cols[j] || dg[a] || udg[b]) { + continue; + } + cols[j] = dg[a] = udg[b] = true; + dfs(i + 1); + cols[j] = dg[a] = udg[b] = false; + } + }; + dfs(0); + return ans; +} +``` + #### C# ```cs diff --git a/solution/0000-0099/0052.N-Queens II/Solution.js b/solution/0000-0099/0052.N-Queens II/Solution.js new file mode 100644 index 0000000000000..9e54ea5796417 --- /dev/null +++ b/solution/0000-0099/0052.N-Queens II/Solution.js @@ -0,0 +1,23 @@ +function totalNQueens(n) { + const cols = Array(10).fill(false); + const dg = Array(20).fill(false); + const udg = Array(20).fill(false); + let ans = 0; + const dfs = i => { + if (i === n) { + ++ans; + return; + } + for (let j = 0; j < n; ++j) { + let [a, b] = [i + j, i - j + n]; + if (cols[j] || dg[a] || udg[b]) { + continue; + } + cols[j] = dg[a] = udg[b] = true; + dfs(i + 1); + cols[j] = dg[a] = udg[b] = false; + } + }; + dfs(0); + return ans; +} diff --git a/solution/0000-0099/0079.Word Search/README.md b/solution/0000-0099/0079.Word Search/README.md index 251a0731df458..f0bb53ed986b2 100644 --- a/solution/0000-0099/0079.Word Search/README.md +++ b/solution/0000-0099/0079.Word Search/README.md @@ -264,6 +264,42 @@ function exist(board: string[][], word: string): boolean { } ``` +#### JavaScript + +```js +function exist(board, word) { + const [m, n] = [board.length, board[0].length]; + const dirs = [-1, 0, 1, 0, -1]; + const dfs = (i, j, k) => { + if (k === word.length - 1) { + return board[i][j] === word[k]; + } + if (board[i][j] !== word[k]) { + return false; + } + const c = board[i][j]; + board[i][j] = '0'; + for (let u = 0; u < 4; ++u) { + const [x, y] = [i + dirs[u], j + dirs[u + 1]]; + const ok = x >= 0 && x < m && y >= 0 && y < n; + if (ok && board[x][y] !== '0' && dfs(x, y, k + 1)) { + return true; + } + } + board[i][j] = c; + return false; + }; + for (let i = 0; i < m; ++i) { + for (let j = 0; j < n; ++j) { + if (dfs(i, j, 0)) { + return true; + } + } + } + return false; +} +``` + #### Rust ```rust diff --git a/solution/0000-0099/0079.Word Search/README_EN.md b/solution/0000-0099/0079.Word Search/README_EN.md index 74075b7865b58..2e35b64450cbb 100644 --- a/solution/0000-0099/0079.Word Search/README_EN.md +++ b/solution/0000-0099/0079.Word Search/README_EN.md @@ -261,6 +261,42 @@ function exist(board: string[][], word: string): boolean { } ``` +#### JavaScript + +```js +function exist(board, word) { + const [m, n] = [board.length, board[0].length]; + const dirs = [-1, 0, 1, 0, -1]; + const dfs = (i, j, k) => { + if (k === word.length - 1) { + return board[i][j] === word[k]; + } + if (board[i][j] !== word[k]) { + return false; + } + const c = board[i][j]; + board[i][j] = '0'; + for (let u = 0; u < 4; ++u) { + const [x, y] = [i + dirs[u], j + dirs[u + 1]]; + const ok = x >= 0 && x < m && y >= 0 && y < n; + if (ok && board[x][y] !== '0' && dfs(x, y, k + 1)) { + return true; + } + } + board[i][j] = c; + return false; + }; + for (let i = 0; i < m; ++i) { + for (let j = 0; j < n; ++j) { + if (dfs(i, j, 0)) { + return true; + } + } + } + return false; +} +``` + #### Rust ```rust diff --git a/solution/0000-0099/0079.Word Search/Solution.js b/solution/0000-0099/0079.Word Search/Solution.js new file mode 100644 index 0000000000000..068b77d9588f0 --- /dev/null +++ b/solution/0000-0099/0079.Word Search/Solution.js @@ -0,0 +1,31 @@ +function exist(board, word) { + const [m, n] = [board.length, board[0].length]; + const dirs = [-1, 0, 1, 0, -1]; + const dfs = (i, j, k) => { + if (k === word.length - 1) { + return board[i][j] === word[k]; + } + if (board[i][j] !== word[k]) { + return false; + } + const c = board[i][j]; + board[i][j] = '0'; + for (let u = 0; u < 4; ++u) { + const [x, y] = [i + dirs[u], j + dirs[u + 1]]; + const ok = x >= 0 && x < m && y >= 0 && y < n; + if (ok && board[x][y] !== '0' && dfs(x, y, k + 1)) { + return true; + } + } + board[i][j] = c; + return false; + }; + for (let i = 0; i < m; ++i) { + for (let j = 0; j < n; ++j) { + if (dfs(i, j, 0)) { + return true; + } + } + } + return false; +} diff --git a/solution/1800-1899/1823.Find the Winner of the Circular Game/Solution.rs b/solution/1800-1899/1823.Find the Winner of the Circular Game/Solution.rs index 1e5c3c839521c..ea4fa35d71619 100644 --- a/solution/1800-1899/1823.Find the Winner of the Circular Game/Solution.rs +++ b/solution/1800-1899/1823.Find the Winner of the Circular Game/Solution.rs @@ -3,7 +3,7 @@ impl Solution { if n == 1 { return 1; } - let mut ans = (k + Solution::find_the_winner(n - 1, k)) % n; - return if ans == 0 { n } else { ans }; + let mut ans = (k + Solution::find_the_winner(n - 1, k)) % n; + return if ans == 0 { n } else { ans }; } } diff --git a/solution/3200-3299/3205.Maximum Array Hopping Score I/README.md b/solution/3200-3299/3205.Maximum Array Hopping Score I/README.md index a48f4b0b2f2fd..2eb2746a9c659 100644 --- a/solution/3200-3299/3205.Maximum Array Hopping Score I/README.md +++ b/solution/3200-3299/3205.Maximum Array Hopping Score I/README.md @@ -2,6 +2,11 @@ comments: true difficulty: 中等 edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3205.Maximum%20Array%20Hopping%20Score%20I/README.md +tags: + - 栈 + - 数组 + - 动态规划 + - 单调栈 --- diff --git a/solution/3200-3299/3205.Maximum Array Hopping Score I/README_EN.md b/solution/3200-3299/3205.Maximum Array Hopping Score I/README_EN.md index 43195076335af..b944e0d127bbc 100644 --- a/solution/3200-3299/3205.Maximum Array Hopping Score I/README_EN.md +++ b/solution/3200-3299/3205.Maximum Array Hopping Score I/README_EN.md @@ -2,6 +2,11 @@ comments: true difficulty: Medium edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3205.Maximum%20Array%20Hopping%20Score%20I/README_EN.md +tags: + - Stack + - Array + - Dynamic Programming + - Monotonic Stack --- diff --git a/solution/3200-3299/3206.Alternating Groups I/README.md b/solution/3200-3299/3206.Alternating Groups I/README.md index 6f6a52fb79071..13e5f8ae452d0 100644 --- a/solution/3200-3299/3206.Alternating Groups I/README.md +++ b/solution/3200-3299/3206.Alternating Groups I/README.md @@ -2,6 +2,9 @@ comments: true difficulty: 简单 edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3206.Alternating%20Groups%20I/README.md +tags: + - 数组 + - 滑动窗口 --- diff --git a/solution/3200-3299/3206.Alternating Groups I/README_EN.md b/solution/3200-3299/3206.Alternating Groups I/README_EN.md index 4dcf92fa88567..f955404325211 100644 --- a/solution/3200-3299/3206.Alternating Groups I/README_EN.md +++ b/solution/3200-3299/3206.Alternating Groups I/README_EN.md @@ -2,6 +2,9 @@ comments: true difficulty: Easy edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3206.Alternating%20Groups%20I/README_EN.md +tags: + - Array + - Sliding Window --- diff --git a/solution/3200-3299/3207.Maximum Points After Enemy Battles/README.md b/solution/3200-3299/3207.Maximum Points After Enemy Battles/README.md index f3eb03373c404..7b186e1d37b5a 100644 --- a/solution/3200-3299/3207.Maximum Points After Enemy Battles/README.md +++ b/solution/3200-3299/3207.Maximum Points After Enemy Battles/README.md @@ -2,6 +2,9 @@ comments: true difficulty: 中等 edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3207.Maximum%20Points%20After%20Enemy%20Battles/README.md +tags: + - 贪心 + - 数组 --- diff --git a/solution/3200-3299/3207.Maximum Points After Enemy Battles/README_EN.md b/solution/3200-3299/3207.Maximum Points After Enemy Battles/README_EN.md index 8764715d42a0a..ca3f5e671014d 100644 --- a/solution/3200-3299/3207.Maximum Points After Enemy Battles/README_EN.md +++ b/solution/3200-3299/3207.Maximum Points After Enemy Battles/README_EN.md @@ -2,6 +2,9 @@ comments: true difficulty: Medium edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3207.Maximum%20Points%20After%20Enemy%20Battles/README_EN.md +tags: + - Greedy + - Array --- diff --git a/solution/3200-3299/3208.Alternating Groups II/README.md b/solution/3200-3299/3208.Alternating Groups II/README.md index fbed6c2d77342..a2a42683fd46f 100644 --- a/solution/3200-3299/3208.Alternating Groups II/README.md +++ b/solution/3200-3299/3208.Alternating Groups II/README.md @@ -2,6 +2,9 @@ comments: true difficulty: 中等 edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3208.Alternating%20Groups%20II/README.md +tags: + - 数组 + - 滑动窗口 --- diff --git a/solution/3200-3299/3208.Alternating Groups II/README_EN.md b/solution/3200-3299/3208.Alternating Groups II/README_EN.md index 2c2cc7e8acc4e..70a06159d6e20 100644 --- a/solution/3200-3299/3208.Alternating Groups II/README_EN.md +++ b/solution/3200-3299/3208.Alternating Groups II/README_EN.md @@ -2,6 +2,9 @@ comments: true difficulty: Medium edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3208.Alternating%20Groups%20II/README_EN.md +tags: + - Array + - Sliding Window --- diff --git a/solution/3200-3299/3209.Number of Subarrays With AND Value of K/README.md b/solution/3200-3299/3209.Number of Subarrays With AND Value of K/README.md index 9cbe8ab9bded6..b4e01a11e8e7e 100644 --- a/solution/3200-3299/3209.Number of Subarrays With AND Value of K/README.md +++ b/solution/3200-3299/3209.Number of Subarrays With AND Value of K/README.md @@ -2,6 +2,11 @@ comments: true difficulty: 困难 edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3209.Number%20of%20Subarrays%20With%20AND%20Value%20of%20K/README.md +tags: + - 位运算 + - 线段树 + - 数组 + - 二分查找 --- diff --git a/solution/3200-3299/3209.Number of Subarrays With AND Value of K/README_EN.md b/solution/3200-3299/3209.Number of Subarrays With AND Value of K/README_EN.md index c1d155c8f6e7f..e3fcea5a71fe0 100644 --- a/solution/3200-3299/3209.Number of Subarrays With AND Value of K/README_EN.md +++ b/solution/3200-3299/3209.Number of Subarrays With AND Value of K/README_EN.md @@ -2,6 +2,11 @@ comments: true difficulty: Hard edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3209.Number%20of%20Subarrays%20With%20AND%20Value%20of%20K/README_EN.md +tags: + - Bit Manipulation + - Segment Tree + - Array + - Binary Search --- diff --git a/solution/3200-3299/3210.Find the Encrypted String/README.md b/solution/3200-3299/3210.Find the Encrypted String/README.md index a5775a7640bef..7d494a649f799 100644 --- a/solution/3200-3299/3210.Find the Encrypted String/README.md +++ b/solution/3200-3299/3210.Find the Encrypted String/README.md @@ -2,6 +2,8 @@ comments: true difficulty: 简单 edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3210.Find%20the%20Encrypted%20String/README.md +tags: + - 字符串 --- diff --git a/solution/3200-3299/3210.Find the Encrypted String/README_EN.md b/solution/3200-3299/3210.Find the Encrypted String/README_EN.md index d509f8421cdbb..19a55052eace1 100644 --- a/solution/3200-3299/3210.Find the Encrypted String/README_EN.md +++ b/solution/3200-3299/3210.Find the Encrypted String/README_EN.md @@ -2,6 +2,8 @@ comments: true difficulty: Easy edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3210.Find%20the%20Encrypted%20String/README_EN.md +tags: + - String --- diff --git a/solution/3200-3299/3211.Generate Binary Strings Without Adjacent Zeros/README.md b/solution/3200-3299/3211.Generate Binary Strings Without Adjacent Zeros/README.md index af96e053ad8ee..d1169b1cf7f3b 100644 --- a/solution/3200-3299/3211.Generate Binary Strings Without Adjacent Zeros/README.md +++ b/solution/3200-3299/3211.Generate Binary Strings Without Adjacent Zeros/README.md @@ -2,6 +2,10 @@ comments: true difficulty: 中等 edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3211.Generate%20Binary%20Strings%20Without%20Adjacent%20Zeros/README.md +tags: + - 位运算 + - 递归 + - 字符串 --- diff --git a/solution/3200-3299/3211.Generate Binary Strings Without Adjacent Zeros/README_EN.md b/solution/3200-3299/3211.Generate Binary Strings Without Adjacent Zeros/README_EN.md index 4f8800aeabc54..14dc2ab98e423 100644 --- a/solution/3200-3299/3211.Generate Binary Strings Without Adjacent Zeros/README_EN.md +++ b/solution/3200-3299/3211.Generate Binary Strings Without Adjacent Zeros/README_EN.md @@ -2,6 +2,10 @@ comments: true difficulty: Medium edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3211.Generate%20Binary%20Strings%20Without%20Adjacent%20Zeros/README_EN.md +tags: + - Bit Manipulation + - Recursion + - String --- diff --git a/solution/3200-3299/3212.Count Submatrices With Equal Frequency of X and Y/README.md b/solution/3200-3299/3212.Count Submatrices With Equal Frequency of X and Y/README.md index 1bf8be06470a4..8a55c146733cd 100644 --- a/solution/3200-3299/3212.Count Submatrices With Equal Frequency of X and Y/README.md +++ b/solution/3200-3299/3212.Count Submatrices With Equal Frequency of X and Y/README.md @@ -2,6 +2,10 @@ comments: true difficulty: 中等 edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3212.Count%20Submatrices%20With%20Equal%20Frequency%20of%20X%20and%20Y/README.md +tags: + - 数组 + - 矩阵 + - 前缀和 --- diff --git a/solution/3200-3299/3212.Count Submatrices With Equal Frequency of X and Y/README_EN.md b/solution/3200-3299/3212.Count Submatrices With Equal Frequency of X and Y/README_EN.md index 22f0246d90563..d7c8fb3e460e0 100644 --- a/solution/3200-3299/3212.Count Submatrices With Equal Frequency of X and Y/README_EN.md +++ b/solution/3200-3299/3212.Count Submatrices With Equal Frequency of X and Y/README_EN.md @@ -2,6 +2,10 @@ comments: true difficulty: Medium edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3212.Count%20Submatrices%20With%20Equal%20Frequency%20of%20X%20and%20Y/README_EN.md +tags: + - Array + - Matrix + - Prefix Sum --- diff --git a/solution/3200-3299/3213.Construct String with Minimum Cost/README.md b/solution/3200-3299/3213.Construct String with Minimum Cost/README.md index 7433c69d2fff4..5a2d06667d114 100644 --- a/solution/3200-3299/3213.Construct String with Minimum Cost/README.md +++ b/solution/3200-3299/3213.Construct String with Minimum Cost/README.md @@ -2,6 +2,11 @@ comments: true difficulty: 困难 edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3213.Construct%20String%20with%20Minimum%20Cost/README.md +tags: + - 数组 + - 字符串 + - 动态规划 + - 后缀数组 --- diff --git a/solution/3200-3299/3213.Construct String with Minimum Cost/README_EN.md b/solution/3200-3299/3213.Construct String with Minimum Cost/README_EN.md index 67d866fafefcd..c9c9d354943bc 100644 --- a/solution/3200-3299/3213.Construct String with Minimum Cost/README_EN.md +++ b/solution/3200-3299/3213.Construct String with Minimum Cost/README_EN.md @@ -2,6 +2,11 @@ comments: true difficulty: Hard edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3213.Construct%20String%20with%20Minimum%20Cost/README_EN.md +tags: + - Array + - String + - Dynamic Programming + - Suffix Array --- diff --git a/solution/3200-3299/3214.Year on Year Growth Rate/README.md b/solution/3200-3299/3214.Year on Year Growth Rate/README.md new file mode 100644 index 0000000000000..f9f960282e758 --- /dev/null +++ b/solution/3200-3299/3214.Year on Year Growth Rate/README.md @@ -0,0 +1,162 @@ +--- +comments: true +difficulty: 困难 +edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3214.Year%20on%20Year%20Growth%20Rate/README.md +tags: + - 数据库 +--- + + + +# [3214. 同比增长率 🔒](https://leetcode.cn/problems/year-on-year-growth-rate) + +[English Version](/solution/3200-3299/3214.Year%20on%20Year%20Growth%20Rate/README_EN.md) + +## 题目描述 + + + +
表:user_transactions
++------------------+----------+ +| Column Name | Type | ++------------------+----------+ +| transaction_id | integer | +| product_id | integer | +| spend | decimal | +| transaction_date | datetime | ++------------------+----------+ +transaction_id 列唯一标识了表中的每一列。 +这张表的每一行含有交易 ID,产品 ID,总花费以及交易日期。 ++ +
编写一个解决方案来计算 每个产品 总支出的 同比增长率。
+ +结果表应该包含以下列:
+ +year
:交易的年份。product_id
:产品的 ID。curr_year_spend
:当年的总支出。prev_year_spend
:上一年的总支出。yoy_rate
:同比增速百分比,四舍五入至小数点后 2 位。返回结果表以 product_id
,year
升序 排序。
结果格式如下所示。
+ ++ +
示例:
+ +输入:
+ +user_transactions
表:
++----------------+------------+---------+---------------------+ +| transaction_id | product_id | spend | transaction_date | ++----------------+------------+---------+---------------------+ +| 1341 | 123424 | 1500.60 | 2019-12-31 12:00:00 | +| 1423 | 123424 | 1000.20 | 2020-12-31 12:00:00 | +| 1623 | 123424 | 1246.44 | 2021-12-31 12:00:00 | +| 1322 | 123424 | 2145.32 | 2022-12-31 12:00:00 | ++----------------+------------+---------+---------------------+ ++ +
输出:
+ +++------+------------+----------------+----------------+----------+ +| year | product_id | curr_year_spend| prev_year_spend| yoy_rate | ++------+------------+----------------+----------------+----------+ +| 2019 | 123424 | 1500.60 | NULL | NULL | +| 2020 | 123424 | 1000.20 | 1500.60 | -33.35 | +| 2021 | 123424 | 1246.44 | 1000.20 | 24.62 | +| 2022 | 123424 | 2145.32 | 1246.44 | 72.12 | ++------+------------+----------------+----------------+----------+ ++ +
解释:
+ +注意:输出表以 product_id
和 year
升序排序。
Table: user_transactions
++------------------+----------+ +| Column Name | Type | ++------------------+----------+ +| transaction_id | integer | +| product_id | integer | +| spend | decimal | +| transaction_date | datetime | ++------------------+----------+ +The transaction_id column uniquely identifies each row in this table. +Each row of this table contains the transaction ID, product ID, the spend amount, and the transaction date. ++ +
Write a solution to calculate the year-on-year growth rate for the total spend for each product.
+ +The result table should include the following columns:
+ +year
: The year of the transaction.product_id
: The ID of the product.curr_year_spend
: The total spend for the current year.prev_year_spend
: The total spend for the previous year.yoy_rate
: The year-on-year growth rate percentage, rounded to 2
decimal places.Return the result table ordered by product_id
,year
in ascending order.
The result format is in the following example.
+ ++
Example:
+ +Input:
+ +user_transactions
table:
++----------------+------------+---------+---------------------+ +| transaction_id | product_id | spend | transaction_date | ++----------------+------------+---------+---------------------+ +| 1341 | 123424 | 1500.60 | 2019-12-31 12:00:00 | +| 1423 | 123424 | 1000.20 | 2020-12-31 12:00:00 | +| 1623 | 123424 | 1246.44 | 2021-12-31 12:00:00 | +| 1322 | 123424 | 2145.32 | 2022-12-31 12:00:00 | ++----------------+------------+---------+---------------------+ ++ +
Output:
+ +++------+------------+----------------+----------------+----------+ +| year | product_id | curr_year_spend| prev_year_spend| yoy_rate | ++------+------------+----------------+----------------+----------+ +| 2019 | 123424 | 1500.60 | NULL | NULL | +| 2020 | 123424 | 1000.20 | 1500.60 | -33.35 | +| 2021 | 123424 | 1246.44 | 1000.20 | 24.62 | +| 2022 | 123424 | 2145.32 | 1246.44 | 72.12 | ++------+------------+----------------+----------------+----------+ ++ +
Explanation:
+ +Note: Output table is ordered by product_id
and year
in ascending order.