Php Postgres查询矩阵表
我想在MySQL或postgres中进行查询,该查询将由4个表生成 请参见下表 我想要postgres或sql查询下面定义的矩阵表 如何使用SQL实现这一点 事先非常感谢 表格:目标Php Postgres查询矩阵表,php,mysql,postgresql,matrix,Php,Mysql,Postgresql,Matrix,我想在MySQL或postgres中进行查询,该查询将由4个表生成 请参见下表 我想要postgres或sql查询下面定义的矩阵表 如何使用SQL实现这一点 事先非常感谢 表格:目标 +----+-------------+ | id | name | +----+-------------+ | 1 | 9999999991 | | 2 | 9999999992 | | 3 | 9999999993 | | 4 | 9999999994 | | 5 | 9999
+----+-------------+
| id | name |
+----+-------------+
| 1 | 9999999991 |
| 2 | 9999999992 |
| 3 | 9999999993 |
| 4 | 9999999994 |
| 5 | 9999999995 |
| 6 | 9999999996 |
| 7 | 9999999997 |
| 8 | 9999999998 |
+----+-------------+
+----+-------------+
| id | name |
+----+-------------+
| 1 | Group 1 |
| 2 | Group 2 |
| 3 | Group 3 |
| 4 | Group 4 |
+----+-------------+
+----+-----------+--------------+
| id | caller | called |
+----+-----------+--------------+
| 1 | 9999999995| 9999999996 |
| 2 | 9999999992| 9999999998 |
| 3 | 9999999993| 9999999998 |
| 4 | 9999999994| 9999999991 |
| 5 | 9999999995| 9999999998 |
| 6 | 9999999996| 9999999992 |
| 6 | 9999999991| 9999999993 |
| 6 | 9999999992| 9999999998 |
+----+-----------+--------------+
表格:目标群体
+----+-------------+
| id | name |
+----+-------------+
| 1 | 9999999991 |
| 2 | 9999999992 |
| 3 | 9999999993 |
| 4 | 9999999994 |
| 5 | 9999999995 |
| 6 | 9999999996 |
| 7 | 9999999997 |
| 8 | 9999999998 |
+----+-------------+
+----+-------------+
| id | name |
+----+-------------+
| 1 | Group 1 |
| 2 | Group 2 |
| 3 | Group 3 |
| 4 | Group 4 |
+----+-------------+
+----+-----------+--------------+
| id | caller | called |
+----+-----------+--------------+
| 1 | 9999999995| 9999999996 |
| 2 | 9999999992| 9999999998 |
| 3 | 9999999993| 9999999998 |
| 4 | 9999999994| 9999999991 |
| 5 | 9999999995| 9999999998 |
| 6 | 9999999996| 9999999992 |
| 6 | 9999999991| 9999999993 |
| 6 | 9999999992| 9999999998 |
+----+-----------+--------------+
表格:目标群体图
+----+-----------+--------------+
| id |targets | target_groups|
+----+-----------+--------------+
| 1 | 9999999991| 1 |
| 2 | 9999999992| 1 |
| 3 | 9999999993| 2 |
| 4 | 9999999994| 2 |
| 5 | 9999999995| 3 |
| 6 | 9999999996| 3 |
| 6 | 9999999997| 4 |
| 6 | 9999999998| 4 |
+----+-----------+--------------+
表格:呼叫详情
+----+-------------+
| id | name |
+----+-------------+
| 1 | 9999999991 |
| 2 | 9999999992 |
| 3 | 9999999993 |
| 4 | 9999999994 |
| 5 | 9999999995 |
| 6 | 9999999996 |
| 7 | 9999999997 |
| 8 | 9999999998 |
+----+-------------+
+----+-------------+
| id | name |
+----+-------------+
| 1 | Group 1 |
| 2 | Group 2 |
| 3 | Group 3 |
| 4 | Group 4 |
+----+-------------+
+----+-----------+--------------+
| id | caller | called |
+----+-----------+--------------+
| 1 | 9999999995| 9999999996 |
| 2 | 9999999992| 9999999998 |
| 3 | 9999999993| 9999999998 |
| 4 | 9999999994| 9999999991 |
| 5 | 9999999995| 9999999998 |
| 6 | 9999999996| 9999999992 |
| 6 | 9999999991| 9999999993 |
| 6 | 9999999992| 9999999998 |
+----+-----------+--------------+
我想要的矩阵表
+--------+--------+--------+--------+--------+
| | Group 1| Group 2| Group 3| Group 4|
+--------+--------+--------+--------+--------+
| Group 1| - | 1 | - | 2 |
| Group 2| 1 | - | - | 1 |
| Group 3| 1 | - | 1 | 1 |
| Group 4| - | - | - | - |
+--------+--------+--------+--------+--------+
MySQL
这是一个挑战。我将完成所需的两个步骤:
首先,让我们构建(并调试)一个查询,列出所有调用方对,其中一些是重复的。(我们稍后再数一数。)
其次,让我们做透视,计算DUP,默认值为“-”,等等:
SELECT
er_name AS '',
IFNULL(SUM(ed_name = 'Group 1'), '-') AS 'Group 1',
IFNULL(SUM(ed_name = 'Group 2'), '-') AS 'Group 2',
IFNULL(SUM(ed_name = 'Group 3'), '-') AS 'Group 3',
IFNULL(SUM(ed_name = 'Group 4'), '-') AS 'Group 4'
FROM ( ... ) AS y
GROUP BY er_name;
对于“…”,从第一步开始放入整个查询(不包括;
)
SUM
可能看起来很奇怪,但其工作原理如下:其中的布尔表达式变成0(false)或1(true),然后SUM
有效计数
如果组的数量不完全是4,那么您应该放弃在SQL中执行此操作。当然,可以用一个非常复杂的存储过程来构造第二个查询,但这会让我的大脑受伤
每当我进行数据透视时,我都会用客户端语言(如PHP)编写代码。以下sql语句:
SELECT
tg1.name as caller,
tg2.name as called,
SUM(cd.caller IS NOT NULL AND cd.called IS NOT NULL) as cnt
FROM
Target_groups tg1 JOIN Target_groups tg2
LEFT JOIN
Target_groups_map tgm1 ON tg1.id=tgm1.target_groups
LEFT JOIN
Target_groups_map tgm2 ON tg2.id=tgm2.target_groups
LEFT JOIN
Call_details cd ON tgm1.targets=cd.caller AND tgm2.targets=cd.called
GROUP BY
tg1.id,tg2.id;
给出:
+---------+---------+------+
| caller | called | cnt |
+---------+---------+------+
| Group 1 | Group 1 | 0 |
| Group 1 | Group 2 | 1 |
| Group 1 | Group 3 | 0 |
| Group 1 | Group 4 | 2 |
| Group 2 | Group 1 | 1 |
| Group 2 | Group 2 | 0 |
| Group 2 | Group 3 | 0 |
| Group 2 | Group 4 | 1 |
| Group 3 | Group 1 | 1 |
| Group 3 | Group 2 | 0 |
| Group 3 | Group 3 | 1 |
| Group 3 | Group 4 | 1 |
| Group 4 | Group 1 | 0 |
| Group 4 | Group 2 | 0 |
| Group 4 | Group 3 | 0 |
| Group 4 | Group 4 | 0 |
+---------+---------+------+
但是,如果您想要精确格式化打印出来的格式,您需要一个准备好的sql语句,然后按照Rick James先生的话做,如果您需要动态的(事先不知道组名),这里是一个起点:
SET @sql = NULL; SELECT GROUP_CONCAT(DISTINCT(CONCAT('"" as ',quote(name)))) INTO @sql FROM Target_groups; SET @sql = CONCAT("SELECT Target_groups.name, ", @sql, " FROM Target_groups"); PREPARE stmt FROM @sql; EXECUTE stmt;
Statement prepared
+---------+---------+---------+---------+---------+
| name | Group 1 | Group 2 | Group 3 | Group 4 |
+---------+---------+---------+---------+---------+
| Group 1 | | | | |
| Group 2 | | | | |
| Group 3 | | | | |
| Group 4 | | | | |
+---------+---------+---------+---------+---------+
ps-这是为了帮助任何试图解决此+测试的人:
create table Targets (id int, name bigint) engine=innodb;
insert into Targets values (1,9999999991),(2,9999999992),(3,9999999993),(4,9999999994),(5,9999999995),(6,9999999996),(7,9999999997),(8,9999999998);
create table Target_groups (id int, name varchar(16)) engine=innodb;
insert into Target_groups values (1,'Group 1'),(2,'Group 2'),(3,'Group 3'),(4,'Group 4');
create table Target_groups_map (id int,targets bigint,target_groups int) engine=innodb;
insert into Target_groups_map values (1,9999999991,1),(2,9999999992,1),(3,9999999993,2),(4,9999999994,2),(5,9999999995,3),(6,9999999996,3),(6,9999999997,4),(6,9999999998,4);
create table Call_details (id int,caller bigint,called bigint) engine=innodb;
insert into Call_details values (1,9999999995,9999999996),(2,9999999992,9999999998),(3,9999999993,9999999998),(4,9999999994,9999999991),(5,9999999995,9999999998),(6,9999999996,9999999992),(6,9999999991,9999999993),(6,9999999992,9999999998);
在Postgres中,您需要扩展来生成透视表: 使用
交叉表()执行的查询
:
使用聚合函数而不是crosstab()
执行相同的查询:
我提出了一个问题:
Select A.name as caller,A.ToGroupName as called,Count(phone_number) as count
From (
Select G.id,T.phone_number,G.Name,FC.Called,TG.name as ToGroupName
From targets T
LEFT Join target_groups_map GM on GM.targets = T.phone_number
Left Join target_groups G on G.id = GM.target_groups
INNER Join call_details FC on FC.Caller = T.phone_number
INNER Join target_groups_map TGM on TGM.targets = FC.called
Inner Join target_groups TG on TG.id = TGM.target_groups
) A
Group By A.name,A.ToGroupName
Order By A.name,A.ToGroupName
给出输出:
+---------+---------+------+
| caller | called | cnt |
+---------+---------+------+
| Group 1 | Group 2 | 1 |
| Group 1 | Group 4 | 3 |
| Group 1 | Group 5 | 2 |
| Group 2 | Group 1 | 2 |
| Group 2 | Group 4 | 1 |
| Group 2 | Group 5 | 3 |
| Group 3 | Group 1 | 1 |
| Group 3 | Group 3 | 1 |
| Group 3 | Group 4 | 1 |
| Group 3 | Group 5 | 1 |
| Group 4 | Group 2 | 1 |
| Group 5 | Group 2 | 2 |
+---------+---------+------+
已将其转换为矩阵格式您需要
连接方面的帮助吗
?还是“旋转”?或者两者都需要?我只需要想要的输出。您可以使用“联接”或“枢轴”。两者都需要。我想看看你能不能做一部分。