sql - sql中的组合列表
问题描述
id1 | id2 |
---|---|
一个 | 1 |
一个 | 2 |
乙 | 3 |
C | 4 |
这是表格,我想要使用以下代码实现的组合列表
with combinationTable as (
select DENSE_RANK() over (Order By id1) as rn ,id2, id1 from test
)
select c1.id2,c2.id2,c3.id2
from combinationTable c1, combinationTable c2, combinationTable c3
where
c1.rn < c2.rn and
c2.rn < c3.rn
order by c1.rn,c2.rn,c3.rn
但是我需要优化代码而不是硬编码,如果有 4 或 5 个不同的 id1,那么应该有 4 或 5 列 id2 和 4 或 5 次组合表的交叉连接。我们如何以优化的方式根据 id1 列的不同计数选择列和交叉连接
解决方案
要使用动态列重新创建查询,我可以考虑使用Prepared Statement的方法:
SET @cols = NULL;
SET @tables = NULL;
SET @conditions = NULL;
SET @sql = NULL;
SET @cols := (WITH RECURSIVE wo AS (
SELECT 1 idx, COUNT(DISTINCT id1) mxct FROM mytable
UNION ALL
SELECT idx+1, mxct FROM wo WHERE idx+1 <= mxct)
SELECT GROUP_CONCAT(CONCAT('c',idx,'.id2')) FROM wo);
SET @tables := (WITH RECURSIVE wo AS (
SELECT 1 idx, COUNT(DISTINCT id1) mxct FROM mytable
UNION ALL
SELECT idx+1, mxct FROM wo WHERE idx+1 <= mxct)
SELECT GROUP_CONCAT(CONCAT('combinationTable c',idx) SEPARATOR ' CROSS JOIN ') FROM wo);
SET @conditions := (SELECT GROUP_CONCAT(conds SEPARATOR ' AND ')
FROM
(WITH RECURSIVE wo AS (
SELECT 1 idx, COUNT(DISTINCT id1) mxct FROM mytable
UNION ALL
SELECT idx+1, mxct FROM wo WHERE idx+1 <= mxct)
SELECT CONCAT('c',idx,'.rn < c',LAG(idx) OVER (ORDER BY idx DESC),'.rn') conds
FROM wo
ORDER BY idx) A
WHERE conds IS NOT NULL);
SET @sql := (
CONCAT('WITH combinationTable AS (
SELECT DENSE_RANK() OVER (ORDER BY id1) AS rn ,id2, id1 FROM mytable
)
SELECT ',@cols,'
FROM ',@tables,'
WHERE ',@conditions,';'));
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
最终查询将类似于您上面的查询,但临时表和列由当前表中的总行动态生成。所有这些都设置为自己的变量。您可以在演示小提琴中看到更多变量值
推荐阅读
- android - 如何制作水平弹出窗口?
- javascript - 使用jquery在整个html代码中删除/禁用跨度类?
- jquery - jQuery中的多个AJAX请求从多个页面获取相同类型的信息
- javascript - 有没有更好的方法来替换我的双 forEach 方法?
- amazon-web-services - AWS ALB(应用程序负载均衡器)-“502 Bad Gateway”问题
- php - PHP输出在写入文件之前返回一个制表符空间
- c# - Wix Bootstrapper 多语言
- docker - 如何知道负载平衡在 Docker Swarm 中是否有效?
- javascript - 执行查找查询时如何使猫鼬失败
- c# - 将读取 C++ 代码的二进制文件移植到 C#