我有一个复杂的数据库结构。我试图解决它,但无法做到这一点。
我有五张桌子:
User
表格和office_id
Service_list
,其中包含所有服务名称Service
,其中包含基于办公室ID的所有服务信息Service_trasaction
,我们从中获取所有基于id(service.service_id = service_transaction.id
)的服务。现在我需要这样的输出:
[office_name] [count recipients] [service_1] [service_2] .........
=======================================================================
Dhaka 5 4 2
Ctg 0 5 0
Khulna 2 2 0
目前,我只能使用此查询获取办公室名称和总收件人数:
SELECT u.id, u.office_name, COUNT(r.id) AS `count`
FROM users u LEFT JOIN recipient r ON u.id = r.office_id
where(u.type = 'agency' and u.del_status = 0)
GROUP BY u.id, u.office_name;
以下是所有表格的结构:
CREATE TABLE `recipient` (
`id` int(10) NOT NULL,
`name` varchar(100) NOT NULL,
`gender` varchar(10) NOT NULL,
`mobile` varchar(15) NOT NULL,
`age` int(10) NOT NULL,
`reg_no` varchar(10) NOT NULL,
`address` varchar(255) NOT NULL,
`disability_type` int(10) NOT NULL,
`education` varchar(255) NOT NULL,
`office_id` int(10) NOT NULL,
`del_status` tinyint(1) NOT NULL,
`create_date` date NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `users` (
`id` tinyint(4) NOT NULL,
`office_name` varchar(255) DEFAULT NULL,
`district_id` int(10) DEFAULT NULL,
`upazilla_id` int(10) DEFAULT NULL,
`address` varchar(255) DEFAULT NULL,
`mobile` varchar(11) DEFAULT NULL,
`email` varchar(50) DEFAULT NULL,
`username` varchar(50) NOT NULL,
`password` varchar(100) NOT NULL,
`type` varchar(10) NOT NULL,
`del_status` tinyint(1) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
CREATE TABLE `service` (
`id` int(10) NOT NULL,
`recipient_number` int(50) NOT NULL,
`date` date NOT NULL,
`office_id` int(10) NOT NULL,
`del_status` tinyint(1) NOT NULL,
`creation_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `service_list` (
`id` int(3) NOT NULL,
`service_name` varchar(50) NOT NULL,
`del_status` tinyint(1) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `service_transaction` (
`id` int(10) NOT NULL,
`service_transaction_id` int(50) NOT NULL,
`service_id` int(20) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
这里是sql dump file链接:https://file.town/download/cez6u43ikr84by4xrzm34pjrf
答案 0 :(得分:0)
听起来你正试图转动SQL查询的结果,或者生成一个矩阵,其中一个表创建行而另一个表创建列。
如果行和列都是任意列表,则无法执行此操作。如果列是任意列表但是行是固定的,那么在MySQL中也不能这样做,因为MySQL没有PIVOT函数。
如果有一定数量的列被认为不会改变(或者每当其中一个更改时都可以编辑SQL语句),那么您可以通过手动构建聚合函数中的每个列来实现此目的,但它在查询中变得非常混乱,你真的必须考虑你正在做的事情来实现它。
在您的具体示例中,类似这样的方法就是:
SELECT
office_name,
COUNT(*) as count_recipients,
SUM(service.id = 1) AS service_1,
SUM(service.id = 2) AS service_2,
...
SUM(service.id = n) AS service_n
FROM
...etc...
GROUP BY
office_name
正如您所看到的,您无法自动创建这些服务列 - 您必须为每个service.id执行一个服务。最好的情况是,您的软件可以获得所有服务ID的完整列表,并以编程方式使用每个服务ID的列构建查询,但是您可以在查询中返回的列数有限制,因此这只会如此远。
更好的解决方案是在您的演示代码中处理显示,而不是在数据库查询中处理(正如您在上述问题的评论中以令人愉快的命名草莓所示)。