简体   繁体   English

MySQL查询获取动态列及其值

[英]MySQL query get dynamic column and its value

I've got a complex DB structure. 我有一个复杂的数据库结构。 I tried to solve it, but couldn't quite get it right. 我试图解决它,但不能完全正确。

I have five tables: 我有五张桌子:

  1. User table for getting office name and office_id 用于获取办公室名称和office_id User
  2. Service_list , which contains all service names Service_list ,包含所有服务名称
  3. Service , which contains all service info based on office id Service ,包含基于办公室ID的所有服务信息
  4. Service_trasaction , from which we get all services based on id ( service.service_id = service_transaction.id ). Service_trasaction ,我们从中获取所有基于id的service.service_id = service_transaction.idservice.service_id = service_transaction.id )。

Now I need output like this: 现在我需要这样的输出:

[office_name] [count recipients] [service_1] [service_2] .........
=======================================================================
Dhaka               5                4            2
Ctg                 0                5            0
Khulna              2                2            0

Currently, I'm only able to get office name and total recipients , using this query: 目前,我只能使用此查询获取办公室名称和总收件人:

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;

Here is the structure of all the tables: 这是所有表的结构:

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;

here is the sql dump file link : https://file.town/download/cez6u43ikr84by4xrzm34pjrf 这是sql转储文件链接: https//file.town/download/cez6u43ikr84by4xrzm34pjrf

It sounds like you're trying to pivot the results of an SQL query, or generate a matrix where one table creates the rows and the other creates the columns. 听起来你正在试图转动SQL查询的结果,或者生成一个矩阵,其中一个表创建行而另一个表创建列。

If both of the rows and columns are arbitrary lists, you can't do this. 如果行和列都是任意列表,则无法执行此操作。 If the columns are an arbitrary list but the rows are fixed, you also can't do this in MySQL, as MySQL doesn't have a PIVOT function. 如果列是任意列表但是行是固定的,那么在MySQL中也不能这样做,因为MySQL没有PIVOT函数。

If there's a set number of columns thought that won't change (or the SQL statement can be edited every time one of those changes), then you can sort of do this by manually building up each of the columns from aggregate functions, but it gets really really messy in the query and you really have to think about what you're doing to achieve it. 如果有一定数量的列被认为不会改变(或者每当其中一个更改时都可以编辑SQL语句),那么您可以通过手动构建聚合函数中的每个列来实现此目的,但是在查询中变得非常混乱,你真的必须考虑你正在做什么来实现它。

In your specific example, something like this would be the approach for that: 在您的具体示例中,类似这样的方法将是:

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

As you can see, you can't have it automatically create those service columns - you have to do one for each service.id. 如您所见,您不能自动创建这些服务列 - 您必须为每个service.id执行一个。 At best, your software could get the full list of all service id's, and programmatically build the query with a column for each service id, but there are limits to the number of columns you can return in a query, so this will only go so far. 最好的情况是,您的软件可以获得所有服务ID的完整列表,并以编程方式使用每个服务ID的列构建查询,但是您可以在查询中返回的列数有限制,因此这只会如此远。

Much better solution is to handle the display in your presentation code, not in the database query (as suggested by the delectably named Strawberry in the comments on your question above). 更好的解决方案是在您的演示代码中处理显示,而不是在数据库查询中处理(正如您在上述问题的评论中提到的名称为Strawberry)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM