做个笔记,根据列A统计列B的数量

SQL统计用户主题数量
本文介绍了一种使用SQL语句来统计不同用户所拥有的主题数量的方法。通过具体实例展示了如何利用GROUP BY和COUNT函数来实现这一统计需求。

需求描述:

根据列username,对列subject的数量进行统计

 

表的记录集:

+----+---------+----------+

| id | subject | username |

+----+---------+----------+

|  1 | 记录一  | admin    |

|  2 | 记录二  | admin    |

|  3 | 记录三  | admin    |

|  4 | 记录四  | test1    |

|  5 | 记录五  | test2    |

|  6 | 记录六  | test2    |

+----+---------+----------+

 

需要的结果:

+----------+-----+

| username | num |

+----------+-----+

| admin    |   3 |

| test1    |   1 |

| test2    |   2 |

+----------+-----+

 

 

SQL:select username,count(subject) as num from 表名 group by username

 

<think>我们有一个二维数组(或表格数据),需要根据用户指定的某一(假设索引为colIndex)将数据分成两个数组: 1. sameValues: 包含指定的值出现多次的所有行(即重复值所在行) 2. diffValues: 包含指定的值只出现一次的所有行(即唯一值所在行) 步骤: 1. 遍历数据,统计指定每个值出现的次数。 2. 再次遍历数据,根据指定的值在统计中出现次数大于1的放入sameValues数组,否则放入diffValues数组。 注意:索引colIndex可能由用户指定(例如0表示第一,1表示第二等),因此我们需要将其作为参数。 假设数据存储在一个二维数组中,每一行是一个数组,索引从0开始。 我们写一个函数来实现: 伪代码: function splitDataByColumn(data, colIndex): countMap = {} // 用于统计每个值出现的次数 // 第一遍遍历:统计 for each row in data: value = row[colIndex] countMap[value] = (countMap[value] || 0) + 1 sameValues = [] // 存储相同值的数据行 diffValues = [] // 存储不同值(唯一值)的数据行 // 第二遍遍历:分配 for each row in data: value = row[colIndex] if countMap[value] > 1: sameValues.append(row) else: diffValues.append(row) return { sameValues, diffValues } 注意:如果数据量很大,两次遍历是必要的,但时间复杂度是O(n),可以接受。 示例(使用JavaScript): 假设数据: data = [ [1, 'A', 100], [2, 'B', 200], [3, 'A', 300], [4, 'C', 400] ] 指定索引为1(第二): 'A'出现2次,'B'和'C'各1次。 则sameValues = [ [1, 'A', 100], [3, 'A', 300] ] diffValues = [ [2, 'B', 200], [4, 'C', 400] ] 在编程实现时,注意索引可能超出范围,需要处理异常。 下面用JavaScript实现一个函数:</think># 根据动态指定将数据分组为相同值和不同值的数组 根据您的需求,我将设计一个解决方案,让您能够根据任意指定的将数据分为两个数组:一个包含该值相同的数据行,另一个包含该值不同的数据行。 ## 解决方案思路 1. **数据准备**:使用二维数组表示表格数据 2. **选择**:允许动态指定分组依据的索引 3. **分组算法**: - 统计指定每个值出现的次数 - 第一次遍历:创建值出现次数的映射 - 第二次遍历:根据出现次数将数据行分配到相同值数组或不同值数组 4. **结果展示**:清晰展示分组结果和统计信息 下面是完整的实现代码: ```html <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>动态数据分组工具</title> <style> * { box-sizing: border-box; margin: 0; padding: 0; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background: linear-gradient(135deg, #1a2a6c, #2c3e50, #1a2a6c); color: #333; min-height: 100vh; padding: 20px; display: flex; flex-direction: column; align-items: center; } .container { max-width: 1200px; width: 100%; background-color: rgba(255, 255, 255, 0.95); border-radius: 15px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3); overflow: hidden; margin: 20px 0; } header { background: linear-gradient(to right, #2c3e50, #4a6491); color: white; padding: 25px 40px; text-align: center; } h1 { font-size: 2.5rem; margin-bottom: 10px; text-shadow: 0 2px 4px rgba(0,0,0,0.3); } .subtitle { font-size: 1.2rem; opacity: 0.9; max-width: 800px; margin: 0 auto; } .controls-section { padding: 30px; background-color: #f8f9fa; border-bottom: 1px solid #e0e0e0; display: flex; flex-direction: column; align-items: center; } .column-selector { display: flex; flex-wrap: wrap; gap: 15px; align-items: center; margin: 20px 0; width: 100%; max-width: 600px; justify-content: center; } .column-selector label { font-size: 1.1rem; font-weight: 600; color: #2c3e50; } .column-selector select { padding: 10px 15px; border: 2px solid #3498db; border-radius: 5px; font-size: 1rem; min-width: 200px; background-color: white; } .controls { display: flex; gap: 15px; margin-top: 20px; flex-wrap: wrap; justify-content: center; } button { padding: 12px 25px; background: linear-gradient(to right, #3498db, #2980b9); color: white; border: none; border-radius: 5px; cursor: pointer; font-size: 16px; transition: all 0.3s ease; display: flex; align-items: center; gap: 8px; } button i { font-size: 20px; } button:hover { transform: translateY(-2px); box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); } .stats { display: flex; justify-content: center; gap: 30px; margin: 20px 0; flex-wrap: wrap; } .stat-card { background: white; border-radius: 10px; padding: 20px; min-width: 200px; text-align: center; box-shadow: 0 4px 8px rgba(0,0,0,0.1); } .stat-value { font-size: 2.5rem; font-weight: bold; margin: 10px 0; } .same-value { color: #27ae60; } .diff-value { color: #e74c3c; } .stat-label { font-size: 1.1rem; color: #7f8c8d; } .results-section { padding: 20px; display: flex; flex-direction: column; gap: 30px; } .result-group { background-color: white; border-radius: 10px; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.08); overflow: hidden; } .group-header { padding: 15px 20px; font-size: 1.4rem; color: white; display: flex; align-items: center; gap: 10px; } .same-header { background: linear-gradient(to right, #27ae60, #2ecc71); } .diff-header { background: linear-gradient(to right, #e74c3c, #c0392b); } .table-container { overflow-x: auto; padding: 15px; } table { width: 100%; border-collapse: collapse; min-width: 600px; } th { background-color: #f1f8e9; color: #2c3e50; font-weight: 600; padding: 12px 15px; text-align: left; border-bottom: 2px solid #7cb342; } td { padding: 10px 15px; border-bottom: 1px solid #e0e0e0; } tr:nth-child(even) { background-color: #f9f9f9; } tr:hover { background-color: #e8f5e9; } .highlight-col { background-color: #e3f2fd !important; font-weight: bold; } .status { padding: 15px; margin: 20px 0; border-radius: 8px; background-color: #e3f2fd; text-align: center; font-size: 18px; color: #1976d2; } .data-table { margin: 20px auto; width: 95%; } footer { text-align: center; padding: 20px; color: white; font-size: 1rem; margin-top: auto; } @media (max-width: 768px) { .container { margin: 10px; } h1 { font-size: 2rem; } .controls { flex-direction: column; } button { width: 100%; } .column-selector { flex-direction: column; } } </style> </head> <body> <div class="container"> <header> <h1>动态数据分组工具</h1> <p class="subtitle">根据任意指定将数据分为相同值和唯一值两组</p> </header> <div class="controls-section"> <div class="column-selector"> <label for="columnSelect">选择分组依据:</label> <select id="columnSelect"> <option value="1">产品代码 (B)</option> <option value="2">产品名称 (C)</option> <option value="3">数量 (D)</option> <option value="4">价格 (E)</option> </select> </div> <div class="controls"> <button id="processBtn"> <i>⚙️</i> 执行分组 </button> <button id="resetBtn"> <i>🔄</i> 重置结果 </button> </div> </div> <div class="status" id="status"> 请选择分组依据并点击"执行分组"按钮 </div> <div class="stats" id="stats" style="display:none;"> <div class="stat-card"> <div class="stat-value same-value" id="sameCount">0</div> <div class="stat-label">相同值的数据行</div> </div> <div class="stat-card"> <div class="stat-value diff-value" id="diffCount">0</div> <div class="stat-label">唯一值的数据行</div> </div> <div class="stat-card"> <div class="stat-value" id="totalCount">0</div> <div class="stat-label">总数据行</div> </div> </div> <div class="results-section"> <div class="result-group"> <div class="group-header same-header"> <i>🔁</i> 相同值数据(重复值) </div> <div class="table-container"> <div id="sameTable">请先执行分组操作</div> </div> </div> <div class="result-group"> <div class="group-header diff-header"> <i>🔑</i> 唯一值数据 </div> <div class="table-container"> <div id="diffTable">请先执行分组操作</div> </div> </div> </div> </div> <footer> <p>动态数据分组工具 © 2023 | 基于JavaScript实现</p> </footer> <script> document.addEventListener('DOMContentLoaded', function() { const columnSelect = document.getElementById('columnSelect'); const processBtn = document.getElementById('processBtn'); const resetBtn = document.getElementById('resetBtn'); const status = document.getElementById('status'); const sameTable = document.getElementById('sameTable'); const diffTable = document.getElementById('diffTable'); const stats = document.getElementById('stats'); const sameCount = document.getElementById('sameCount'); const diffCount = document.getElementById('diffCount'); const totalCount = document.getElementById('totalCount'); // 示例数据(二维数组) const data = [ ['ID', '产品代码', '产品名称', '数量', '价格'], [1, 'P100', '笔记本电脑', 5, 1200], [2, 'P101', '无线鼠标', 20, 25], [3, 'P100', '笔记本电脑', 3, 1200], [4, 'P102', '机械键盘', 15, 80], [5, 'P103', '显示器', 8, 300], [6, 'P101', '无线鼠标', 12, 25], [7, 'P104', '耳机', 25, 50], [8, 'P100', '笔记本电脑', 7, 1200], [9, 'P105', 'USB-C线', 50, 10], [10, 'P102', '机械键盘', 10, 80], [11, 'P106', '电源适配器', 15, 45], [12, 'P107', '扩展坞', 8, 120], [13, 'P108', '网络摄像头', 12, 65], [14, 'P109', '麦克风', 6, 85], [15, 'P110', '音箱', 9, 150] ]; // 显示原始数据表 displayDataTable(data); // 处理数据按钮 processBtn.addEventListener('click', function() { try { // 获取选择的索引(减1因为数组索引从0开始) const colIndex = parseInt(columnSelect.value) - 1; // 提取表头(第一行) const headers = data[0]; // 提取数据(从第二行开始) const dataRows = data.slice(1); // 分组数据 const groupedData = groupByColumn(dataRows, colIndex); // 显示结果 displayResults(headers, groupedData.sameValues, groupedData.diffValues, colIndex); // 更新统计信息 sameCount.textContent = groupedData.sameValues.length; diffCount.textContent = groupedData.diffValues.length; totalCount.textContent = dataRows.length; stats.style.display = 'flex'; status.textContent = `数据处理完成!基于"${headers[colIndex]}"分组 - 相同值: ${groupedData.sameValues.length}行, 唯一值: ${groupedData.diffValues.length}行`; status.style.backgroundColor = '#e3f2fd'; status.style.color = '#1976d2'; } catch (error) { status.textContent = `处理错误: ${error.message}`; status.style.backgroundColor = '#ffebee'; status.style.color = '#c62828'; console.error(error); } }); // 重置按钮 resetBtn.addEventListener('click', function() { sameTable.innerHTML = '请先执行分组操作'; diffTable.innerHTML = '请先执行分组操作'; status.textContent = '请选择分组依据并点击"执行分组"按钮'; status.style.backgroundColor = '#e3f2fd'; status.style.color = '#1976d2'; stats.style.display = 'none'; }); // 根据指定分组数据 function groupByColumn(data, colIndex) { // 统计指定值出现的次数 const valueCount = {}; // 第一遍遍历:统计每个值出现的次数 data.forEach(row => { if (row.length > colIndex) { const value = row[colIndex]; valueCount[value] = (valueCount[value] || 0) + 1; } }); // 第二遍遍历:分组数据 const sameValues = []; // 相同值(重复)的数据 const diffValues = []; // 唯一值的数据 data.forEach(row => { if (row.length > colIndex) { const value = row[colIndex]; if (valueCount[value] > 1) { sameValues.push(row); } else { diffValues.push(row); } } }); return { sameValues, diffValues }; } // 显示原始数据表 function displayDataTable(data) { const container = document.querySelector('.controls-section'); const tableDiv = document.createElement('div'); tableDiv.className = 'table-container'; tableDiv.innerHTML = '<h3 style="text-align:center; margin:15px 0;">原始数据表</h3>'; let html = '<table class="data-table"><thead><tr>'; // 添加表头 data[0].forEach(header => { html += `<th>${header}</th>`; }); html += '</tr></thead><tbody>'; // 添加数据行 for (let i = 1; i < data.length; i++) { html += '<tr>'; data[i].forEach(cell => { html += `<td>${cell}</td>`; }); html += '</tr>'; } html += '</tbody></table>'; tableDiv.innerHTML += html; container.appendChild(tableDiv); } // 显示结果 function displayResults(headers, sameData, diffData, colIndex) { // 显示相同值表格 if (sameData.length > 0) { sameTable.innerHTML = createTableHTML(headers, sameData, colIndex); } else { sameTable.innerHTML = '<p>没有找到相同值的数据</p>'; } // 显示不同值表格 if (diffData.length > 0) { diffTable.innerHTML = createTableHTML(headers, diffData, colIndex); } else { diffTable.innerHTML = '<p>没有找到唯一值的数据</p>'; } } // 创建表格HTML function createTableHTML(headers, data, colIndex) { let html = '<table><thead><tr>'; // 添加表头 headers.forEach((header, index) => { if (index === colIndex) { html += `<th style="background-color: #bbdefb;">${header}</th>`; } else { html += `<th>${header}</th>`; } }); html += '</tr></thead><tbody>'; // 添加数据行 data.forEach(row => { html += '<tr>'; row.forEach((cell, index) => { // 高亮显示分组依据 const cellClass = index === colIndex ? 'class="highlight-col"' : ''; html += `<td ${cellClass}>${cell}</td>`; }); html += '</tr>'; }); html += '</tbody></table>'; return html; } }); </script> </body> </html> ``` ## 功能说明 这个工具实现了根据动态指定的将数据分为两个数组的功能: 1. **动态选择**: - 通过下拉菜单选择分组依据 - 支持选择不同进行分组(示例中包含B、C、D、E) 2. **数据分组算法**: - 使用值出现次数映射进行高效统计 - 时间复杂度为 $O(n)$(其中 $n$ 是数据行数) - 将数据分为: - 相同值数组(分组值出现多次的行) - 不同值数组(分组值唯一的行) 3. **结果展示**: - 清晰展示原始数据表 - 分组结果使用不同颜色区分 - 分组依据高亮显示 - 统计卡片显示分组数量 4. **用户交互**: - 一键执行分组操作 - 一键重置结果 - 响应式设计适配不同设备 ## 使用示例 1. **选择"产品代码 (B)"分组**: - 相同值数组:包含产品代码重复的行(如P100、P101、P102) - 不同值数组:包含产品代码唯一的行(如P103、P104等) 2. **选择"产品名称 (C)"分组**: - 相同值数组:包含相同产品名称的行 - 不同值数组:包含唯一产品名称的行 3. **选择"数量 (D)"分组**: - 相同值数组:包含相同数量的行 - 不同值数组:包含唯一数量的行 ## 算法核心 ```javascript function groupByColumn(data, colIndex) { // 统计指定值出现的次数 const valueCount = {}; // 第一遍遍历:统计 data.forEach(row => { if (row.length > colIndex) { const value = row[colIndex]; valueCount[value] = (valueCount[value] || 0) + 1; } }); // 第二遍遍历:分组 const sameValues = []; // 相同值(重复)的数据 const diffValues = []; // 唯一值的数据 data.forEach(row => { if (row.length > colIndex) { const value = row[colIndex]; if (valueCount[value] > 1) { sameValues.push(row); } else { diffValues.push(row); } } }); return { sameValues, diffValues }; } ``` 该算法的时间复杂度为 $O(n)$,其中 $n$ 是数据行数,因为它只需要两次遍历数据集合[^1]。 ## 相关问题 1. 如何处理包含空值的进行分组? 2. 如何将分组结果导出为CSV或Excel文件? 3. 如何优化算法处理超大数据集(>100,000行)的性能? 4. 如何同时根据进行分组(复合键分组)? 5. 如何实现不区分大小写的文本分组? [^1]: 数组结构通常为多行单数据结构,行数为数组长度,为数组元素。 [^2]: 二维数组可以表示表格数据,行和分别对应表格的行和。 [^3]: 数组合并操作可以通过遍历和条件判断实现。 [^4]: 数组操作有多种方法,可根据需求选择合适的方法。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值