Google Sheets Query查询前如何转换行实现每行单条商品记录
完全可以实现,无需搭建多表关联结构,Google Sheets原生功能即可完成转换,以下是三种可直接落地的方案,按易用性排序:
方案1:固定列范围公式法(最易上手)
适合商品列数量固定、不需要频繁新增商品列的场景,直接将公式输入到目标空白工作表的A1单元格即可自动生成全量结果。
假设原始数据存放在名为Sheet1的工作表中,A列为date、B列为buyer、C列为country,D列及以后为所有商品列,公式如下:
={ "date","buyer","country","item"; ARRAYFORMULA( SPLIT( FLATTEN( FILTER(Sheet1!A2:A,Sheet1!A2:A<>"") & "|" & FILTER(Sheet1!B2:B,Sheet1!A2:A<>"") & "|" & FILTER(Sheet1!C2:C,Sheet1!A2:A<>"") & "|" & FILTER(Sheet1!D2:Z,Sheet1!A2:A<>"") ), "|" ) ) }
逻辑说明:
- 第一行定义目标表的固定表头
FILTER函数自动过滤原始表的空行,避免生成无效数据- 用分隔符
|将每行的固定字段(日期、采购方、国家)和该行所有商品值逐列拼接 FLATTEN将二维的拼接结果拍平为单列SPLIT按分隔符将单列字符串拆分为4列,直接输出符合要求的长表结构
*注意:公式中D2:Z可根据实际商品列的最大范围调整,多预留空列不会影响结果,空值会被自动过滤。
方案2:动态适配范围公式法(免维护)
适合后续会频繁新增商品列、不想每次手动调整公式范围的场景,公式会自动识别有效数据行和商品列数,新增数据/列后自动同步结果:
=QUERY( ARRAYFORMULA(SPLIT(FLATTEN( FILTER(Sheet1!A2:C,Sheet1!A2:A<>"") & "|" & OFFSET(Sheet1!D2,,,COUNTA(Sheet1!A2:A),COUNTA(Sheet1!1:1)-3) ),"|")), "select * where Col4 is not null label Col1'date',Col2'buyer',Col3'country',Col4'item'" )
其中COUNTA(Sheet1!1:1)-3会自动计算表头中除前3个固定字段外的商品列总数,OFFSET动态引用对应范围的商品数据,无需手动修改列范围。
方案3:Apps Script脚本法(适合大数据量/自定义需求)
如果单表数据量超过10万行、公式计算卡顿,或者需要自定义转换规则、定时自动更新,可以用脚本实现:
- 打开原始表格,点击顶部菜单「扩展程序」-「Apps Script」进入脚本编辑器
- 粘贴以下代码,根据实际表名修改代码中的工作表名称,保存后首次运行完成授权即可:
function wideToLong() { const ss = SpreadsheetApp.getActiveSpreadsheet(); const sourceSheet = ss.getSheetByName("Sheet1"); // 替换为原始表名称 const targetSheet = ss.getSheetByName("Sheet2"); // 替换为结果输出表名称 // 读取全量原始数据,过滤空行 const sourceData = sourceSheet.getDataRange().getValues().filter(row => row[0] !== ""); sourceData.shift(); // 移除原表头 const fixedColNum = 3; // 前3列为固定属性列,后续为商品列 const output = [["date","buyer","country","item"]]; // 逐行拆分商品为独立行 sourceData.forEach(row => { const fixedFields = row.slice(0, fixedColNum); const validItems = row.slice(fixedColNum).filter(val => val !== ""); validItems.forEach(item => output.push([...fixedFields, item])); }) // 清空目标表旧数据,写入转换结果 targetSheet.clearContents(); targetSheet.getRange(1, 1, output.length, output[0].length).setValues(output); }
你可以给脚本设置定时触发器,实现原始表更新后自动同步转换结果,也可以在表格内插入绘制按钮绑定脚本,点击即可手动更新。
转换完成后的长表可直接使用QUERY函数做统计查询,例如统计2022年LAT区域的各商品订单量:=QUERY(Sheet2!A:D,"select D,count(A) where A >= date '2022-01-01' and A < date '2023-01-01' and C = 'LAT' group by D label D'商品名',count(A)'订单数'")
不需要搭建多表关联结构即可实现类数据库的查询效果。
内容的提问来源于stack exchange,提问作者J.Valášek

