查询以显示不同的组合,然后显示每个不同组合的计数
Posted
技术标签:
【中文标题】查询以显示不同的组合,然后显示每个不同组合的计数【英文标题】:Query to display distinct combination and then display count for each distinct combination 【发布时间】:2021-01-07 04:47:14 【问题描述】:有一个 transid 字段,此表中将存在多行,其中包含配置值列表。对于所有的 transid,我想按计数检索表组中存在的所有不同的 transid、config_name 和 value 字段组合
我的连接查询没有按预期返回结果。下面是表结构、使用的查询、结果和预期结果
表格
transid config_name value
1 payment_fee instant
2 eligible_account true
1 Block_intl_trans false
5 payment_fee provider_charge
1 eligible_account false
1 KycEligible 0
2 KycEligible 1
5 KycEligible 1
5 Block_intl_trans true
2 Block_intl_trans false
2 payment_fee provider_charge
5 eligible_account true
上面的表格结构意味着下面是每个用户的配置值的组合。
transid KycEligible payment_fee eligible_account Block_intl_trans
1 0 instant false false
2 1 provider_charge true false
5 1 provider_charge true false
下面是我用来将行转换为列然后按 config_name 对它们进行分组的查询(对于每个 config_name,而不是每个配置键和值组合的多行)。然后选择表中存在的 KycEligible、configname 和 value 组合的所有不同组合以及每个不同组合的计数。
select
distinct
max(case when b.config_name = 'KycEligible' then b.config_value end) KycEligible,
max(case when b.config_name = 'payment_fee' then b.config_value end) payment_fee,
max(case when b.config_name = 'eligible_account' then b.config_value end) eligible_account,
max(case when b.config_name = 'Block_intl_trans' then b.config_value end) Block_intl_trans,
count(*) AS COUNT
from tableA b
where b.config_name in ('KycEligible', 'payment_fee', 'eligible_account', 'Block_intl_trans')
group by b.config_name
having count(*) > 1
预期结果:
KycEligible payment_fee eligible_account Block_intl_trans Count
0 instant false false 1
1 provider_charge true false 2
我的查询没有返回预期的结果。有人可以帮忙解决这个问题吗?
【问题讨论】:
请在代码问题中给出minimal reproducible example--cut & paste & runnable code,包括最小的代表性示例输入作为代码;期望和实际输出(包括逐字错误消息);标签和版本;明确的规范和解释。给出尽可能少的代码,即您显示的代码可以通过您显示的代码扩展为不正常的代码。 (调试基础。)对于包含 DBMS 和 DDL(包括约束和索引)和输入为格式化为表的代码的 SQL。 How to Ask 暂停总体目标的工作,将代码砍到第一个表达式,没有给出你期望的内容,说出你期望的内容和原因。 1) 您在文本和源数据示例中的列名不同,因此您的解释不清楚。同步。 2)您在代码中使用了错误的非标准引号字符。正确的。 3) 您在name
列中检查“instant”和“provider_charge”,而这些值在value
列中。 4) 预期结果在 Block_intl_trans=false 的情况下连续显示 Count=2,但 transid=5 的 Block_intl_trans 为 true。
附言。 fiddle
Block_intl_trans
for transid=5 是 false
还是 true
?
考虑处理应用代码中数据显示的问题
【参考方案1】:
我认为你需要这样的东西:
SELECT
KycEligible, payment_fee, eligible_account, Block_intl_trans, COUNT(*) CNT
FROM (
SELECT
(SELECT MAX(t0.config_value) FROM test t0 WHERE t0.config_name = 'KycEligible' AND t0.transid = t.transid) as KycEligible,
(SELECT MAX(t0.config_value) FROM test t0 WHERE t0.config_name = 'payment_fee' AND t0.transid = t.transid) as payment_fee,
(SELECT MAX(t0.config_value) FROM test t0 WHERE t0.config_name = 'eligible_account' AND t0.transid = t.transid) as eligible_account,
(SELECT MAX(t0.config_value) FROM test t0 WHERE t0.config_name = 'Block_intl_trans' AND t0.transid = t.transid) as Block_intl_trans
FROM
test t
GROUP BY t.transid
) dt
GROUP BY KycEligible, payment_fee, eligible_account, Block_intl_trans
;
这将给出以下内容:
ycEligible payment_fee eligible_account Block_intl_trans CNT
0 instant○ false false 1
1 provider_charge true false 1
1 provider_charge true true 1
结果与预期的问题不同:
2 and 5 transids have different Block_intl_trans
1 and 5 transids have different payment_fee
1 and 2 transids have different eligible_account
【讨论】:
我没有投反对票,而是尝试在评论中 Akina 给出的小提琴上运行您的查询。你会发现计数是错误的。【参考方案2】:我给出两个小提琴示例,因为您提供的示例数据不一致。
-
此小提琴适用于 transid=5 且
Block_intl_trans
数据为 true
- 与您的表数据示例一致:https://www.db-fiddle.com/f/r1imsYP8dQxkLSo5SkYcVK/3
此小提琴适用于 transid=5 且 Block_intl_trans
数据为 false
- 与您说明的配置组合一致:https://www.db-fiddle.com/f/r1imsYP8dQxkLSo5SkYcVK/4
我猜唯一的组合将来自所有config_name
值。这是示例查询:
SELECT KycEligible, payment_fee, eligible_account, Block_intl_trans, COUNT(*) FROM
(SELECT transid,
GROUP_CONCAT(CASE WHEN config_name="KycEligible" THEN config_value END) AS "KycEligible",
GROUP_CONCAT(CASE WHEN config_name="payment_fee" THEN config_value END) AS "payment_fee",
GROUP_CONCAT(CASE WHEN config_name="eligible_account" THEN config_value END) AS "eligible_account",
GROUP_CONCAT(CASE WHEN config_name="Block_intl_trans" THEN config_value END) AS "Block_intl_trans"
FROM TableA
GROUP BY transid) V
GROUP BY KycEligible, payment_fee, eligible_account, Block_intl_trans;
【讨论】:
【参考方案3】:使用 Max 进行简单查询, 结果计数可以基于您的输入数据(transid=5、config=Block_intl_trans、value=false 或 value=true)
SELECT KycEligible, payment_fee, eligible_account, Block_intl_trans, COUNT(*) FROM
(
SELECT
transid,
max(CASE WHEN config_name="KycEligible" THEN value END) AS "KycEligible",
max(CASE WHEN config_name="payment_fee" THEN value END) AS "payment_fee",
max(CASE WHEN config_name="eligible_account" THEN value END) AS "eligible_account",
max(CASE WHEN config_name="Block_intl_trans" THEN value END) AS "Block_intl_trans"
FROM <YOUR_TABLE_NAME>
GROUP BY transid
) tmp
GROUP BY KycEligible, payment_fee, eligible_account, Block_intl_trans;
【讨论】:
以上是关于查询以显示不同的组合,然后显示每个不同组合的计数的主要内容,如果未能解决你的问题,请参考以下文章