这是一个使用 expo-sqlite 在我的 expo 应用程序中获取条形图数据的函数,但 sql 查询似乎无法正常工作。
我想要的是创建一个函数,可以获取当月和前 4 个月的总销售额数据。如果数据不存在,则会传递月份名称,数据将为
0
。
表查询:
CREATE TABLE IF NOT EXISTS Sales (id INTEGER PRIMARY KEY NOT NULL,name TEXT NOT NULL,quantity INTEGER NOT NULL,soldPrice REAL NOT NULL,date TEXT NOT NULL);
Sql 查询:
WITH months AS (
SELECT strftime('%Y-%m', date('now', '-5 months', '+' || n || ' months')) AS month
FROM (SELECT 0 AS n UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4)
)
SELECT
CASE strftime('%m', m.month)
WHEN '01' THEN 'Jan'
WHEN '02' THEN 'Feb'
WHEN '03' THEN 'Mar'
WHEN '04' THEN 'Apr'
WHEN '05' THEN 'May'
WHEN '06' THEN 'Jun'
WHEN '07' THEN 'Jul'
WHEN '08' THEN 'Aug'
WHEN '09' THEN 'Sep'
WHEN '10' THEN 'Oct'
WHEN '11' THEN 'Nov'
WHEN '12' THEN 'Dec'
END AS month,
COALESCE(SUM(s.soldPrice * s.quantity), 0) AS total_sales_amount
FROM months m
LEFT JOIN Sales s ON strftime('%Y-%m', s.date) = m.month
GROUP BY m.month
ORDER BY m.month;
图表数据功能:
import * as Sqlite from 'expo-sqlite;
const db = Sqlite.openDatabaseSync('test.db');
const ChartData = async () => {
const labels = [];
const dataset = [0, 0, 0, 0, 0];
const query = `
WITH months AS (
SELECT strftime('%Y-%m', date('now', '-5 months', '+' || n || ' months')) AS month
FROM (SELECT 0 AS n UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4)
)
SELECT
CASE strftime('%m', m.month)
WHEN '01' THEN 'Jan'
WHEN '02' THEN 'Feb'
WHEN '03' THEN 'Mar'
WHEN '04' THEN 'Apr'
WHEN '05' THEN 'May'
WHEN '06' THEN 'Jun'
WHEN '07' THEN 'Jul'
WHEN '08' THEN 'Aug'
WHEN '09' THEN 'Sep'
WHEN '10' THEN 'Oct'
WHEN '11' THEN 'Nov'
WHEN '12' THEN 'Dec'
END AS month,
COALESCE(SUM(s.soldPrice * s.quantity), 0) AS total_sales_amount
FROM months m
LEFT JOIN Sales s ON strftime('%Y-%m', s.date) = m.month
GROUP BY m.month
ORDER BY m.month;`;
const results = await db.getAllAsync(query);
console.log(results) // LOG: [{"month": null, "total_sales_amount": 0}, {"month": null, "total_sales_amount": 0}, {"month": null, "total_sales_amount": 0}, {"month": null, "total_sales_amount": 0}, {"month": null, "total_sales_amount": 0}]
if (results && results.length > 0) {
for (let i = 0; i < results.length; i++) {
const row = results[i];
labels.push(row.month);
dataset[i] = row.total_sales_amount;
}
} else {
const monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
const currentDate = new Date();
const currentMonthIndex = currentDate.getMonth();
for (let i = 0; i < 5; i++) {
const monthIndex = (currentMonthIndex - i + 12) % 12;
labels.unshift(monthNames[monthIndex]);
dataset.unshift(0); // Initialize dataset for these months
}
}
console.log(labels, dataset); //LOG: dataset:[0, 0, 0, 0, 0], labels: [null, null, null, null, null]}
return [labels, dataset];
};
结果:
[{"month": null, "total_sales_amount": 0}, {"month": null, "total_sales_amount": 0}, {"month": null, "total_sales_amount": 0}, {"month": null, "total_sales_amount": 0}, {"month": null , "total_sales_amount": 0}]
我认为如果sql查询可以做到这一点,那就会很高效,那么有没有其他替代方法可以高效地实现这一点。
我试图分解这个过程并一点一点地做,但它大大减慢了过程。
m.month
不是日期,因此 strftime('%m', m.month)
(时间字符串)将产生 null
。尝试使用 substr
代替:
WITH months AS (
SELECT strftime('%Y-%m', date('now', '-5 months', '+' || n || ' months')) AS month
FROM (SELECT 0 AS n UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4)
)
SELECT
CASE substr(m.month, 6)
WHEN '01' THEN 'Jan'
WHEN '02' THEN 'Feb'
WHEN '03' THEN 'Mar'
WHEN '04' THEN 'Apr'
WHEN '05' THEN 'May'
WHEN '06' THEN 'Jun'
WHEN '07' THEN 'Jul'
WHEN '08' THEN 'Aug'
WHEN '09' THEN 'Sep'
WHEN '10' THEN 'Oct'
WHEN '11' THEN 'Nov'
WHEN '12' THEN 'Dec'
END AS month,
COALESCE(SUM(s.soldPrice * s.quantity), 0) AS total_sales_amount
FROM months m
LEFT JOIN Sales s ON strftime('%Y-%m', s.date) = m.month
GROUP BY m.month
ORDER BY m.month;