重塑表格以将行转换为列

发布于 2024-08-01 14:12:31 字数 780 浏览 6 评论 0原文

我尝试搜索帖子,但只找到了 SQL Server/Access 的解决方案。 我需要 MySQL (5.X) 中的解决方案。

我有一个包含 3 列的表(称为历史记录):hostid、itemname、itemvalue。
如果我执行选择(select * from History),它将返回

hostiditemnameitemvalue
1A10
1B3
2A9
2C40

如何查询数据库以返回类似

hostidAB 的内容C
11030
29040

I tried to search posts, but I only found solutions for SQL Server/Access. I need a solution in MySQL (5.X).

I have a table (called history) with 3 columns: hostid, itemname, itemvalue.
If I do a select (select * from history), it will return

hostiditemnameitemvalue
1A10
1B3
2A9
2C40

How do I query the database to return something like

hostidABC
11030
29040

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

梦幻的味道 2024-08-08 14:12:31

您可以使用几个LEFT JOIN。 请使用此代码

SELECT t.hostid,
       COALESCE(t1.itemvalue, 0) A,
       COALESCE(t2.itemvalue, 0) B,
       COALESCE(t3.itemvalue, 0) C 
FROM history t 
LEFT JOIN history t1 
    ON t1.hostid = t.hostid 
    AND t1.itemname = 'A' 
LEFT JOIN history t2 
    ON t2.hostid = t.hostid 
    AND t2.itemname = 'B' 
LEFT JOIN history t3 
    ON t3.hostid = t.hostid 
    AND t3.itemname = 'C' 
GROUP BY t.hostid

You can use a couple of LEFT JOINs. Kindly use this code

SELECT t.hostid,
       COALESCE(t1.itemvalue, 0) A,
       COALESCE(t2.itemvalue, 0) B,
       COALESCE(t3.itemvalue, 0) C 
FROM history t 
LEFT JOIN history t1 
    ON t1.hostid = t.hostid 
    AND t1.itemname = 'A' 
LEFT JOIN history t2 
    ON t2.hostid = t.hostid 
    AND t2.itemname = 'B' 
LEFT JOIN history t3 
    ON t3.hostid = t.hostid 
    AND t3.itemname = 'C' 
GROUP BY t.hostid
青衫负雪 2024-08-08 14:12:31
SELECT 
    hostid, 
    sum( if( itemname = 'A', itemvalue, 0 ) ) AS A,  
    sum( if( itemname = 'B', itemvalue, 0 ) ) AS B, 
    sum( if( itemname = 'C', itemvalue, 0 ) ) AS C 
FROM 
    bob 
GROUP BY 
    hostid;
SELECT 
    hostid, 
    sum( if( itemname = 'A', itemvalue, 0 ) ) AS A,  
    sum( if( itemname = 'B', itemvalue, 0 ) ) AS B, 
    sum( if( itemname = 'C', itemvalue, 0 ) ) AS C 
FROM 
    bob 
GROUP BY 
    hostid;
極樂鬼 2024-08-08 14:12:31

如果您有许多需要旋转的项目,另一个选项特别有用,那就是让 mysql 为您构建查询:

SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'ifnull(SUM(case when itemname = ''',
      itemname,
      ''' then itemvalue end),0) AS `',
      itemname, '`'
    )
  ) INTO @sql
FROM
  history;
SET @sql = CONCAT('SELECT hostid, ', @sql, ' 
                  FROM history 
                   GROUP BY hostid');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

FIDDLE
添加了一些额外的值以查看其工作情况

GROUP_CONCAT 的默认值为 1000,因此如果您有一个非常大的查询,请在运行

SET SESSION group_concat_max_len = 1000000;

测试之前更改此参数:

DROP TABLE IF EXISTS history;
CREATE TABLE history
(hostid INT,
itemname VARCHAR(5),
itemvalue INT);

INSERT INTO history VALUES(1,'A',10),(1,'B',3),(2,'A',9),
(2,'C',40),(2,'D',5),
(3,'A',14),(3,'B',67),(3,'D',8);

  hostid    A     B     C      D
    1     10      3     0      0
    2     9       0    40      5
    3     14     67     0      8

Another option,especially useful if you have many items you need to pivot is to let mysql build the query for you:

SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'ifnull(SUM(case when itemname = ''',
      itemname,
      ''' then itemvalue end),0) AS `',
      itemname, '`'
    )
  ) INTO @sql
FROM
  history;
SET @sql = CONCAT('SELECT hostid, ', @sql, ' 
                  FROM history 
                   GROUP BY hostid');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

FIDDLE
Added some extra values to see it working

GROUP_CONCAT has a default value of 1000 so if you have a really big query change this parameter before running it

SET SESSION group_concat_max_len = 1000000;

Test:

DROP TABLE IF EXISTS history;
CREATE TABLE history
(hostid INT,
itemname VARCHAR(5),
itemvalue INT);

INSERT INTO history VALUES(1,'A',10),(1,'B',3),(2,'A',9),
(2,'C',40),(2,'D',5),
(3,'A',14),(3,'B',67),(3,'D',8);

  hostid    A     B     C      D
    1     10      3     0      0
    2     9       0    40      5
    3     14     67     0      8
鸢与 2024-08-08 14:12:31

我将添加更长、更详细的说明来说明解决此问题所需的步骤。 如果太长,我深表歉意。


我将从您给出的基础开始,并用它来定义几个术语,我将在本文的其余部分使用这些术语。 这将是基表

select * from history;

+--------+----------+-----------+
| hostid | itemname | itemvalue |
+--------+----------+-----------+
|      1 | A        |        10 |
|      1 | B        |         3 |
|      2 | A        |         9 |
|      2 | C        |        40 |
+--------+----------+-----------+

这将是我们的目标,漂亮的数据透视表

select * from history_itemvalue_pivot;

+--------+------+------+------+
| hostid | A    | B    | C    |
+--------+------+------+------+
|      1 |   10 |    3 |    0 |
|      2 |    9 |    0 |   40 |
+--------+------+------+------+

history.hostid 列中的值将变为数据透视表中的 >y 值history.itemname 列中的值将变为 x-values(出于显而易见的原因)。


当我必须解决创建数据透视表的问题时,我使用三步过程(带有可选的第四步)来解决它:

  1. 选择感兴趣的列,即 y 值>x 值
  2. 使用额外的列扩展基表 - 每个 x 值
  3. 组一列,并聚合扩展表 - 每个 y 值一组) strong>
  4. (可选)美化聚合表

让我们将这些步骤应用于您的问题,看看会得到什么:

第 1 步:选择感兴趣的列。 在所需的结果中,hostid 提供y 值itemname 提供x 值

第 2 步:使用额外的列扩展基表。 我们通常需要每个 x 值一列。 回想一下,我们的 x 值列是 itemname

create view history_extended as (
  select
    history.*,
    case when itemname = "A" then itemvalue end as A,
    case when itemname = "B" then itemvalue end as B,
    case when itemname = "C" then itemvalue end as C
  from history
);

select * from history_extended;

+--------+----------+-----------+------+------+------+
| hostid | itemname | itemvalue | A    | B    | C    |
+--------+----------+-----------+------+------+------+
|      1 | A        |        10 |   10 | NULL | NULL |
|      1 | B        |         3 | NULL |    3 | NULL |
|      2 | A        |         9 |    9 | NULL | NULL |
|      2 | C        |        40 | NULL | NULL |   40 |
+--------+----------+-----------+------+------+------+

请注意,我们没有更改行数 - 我们只是添加了额外的列。 另请注意 NULL 的模式 - 具有 itemname = "A" 的行的新列 A 具有非空值,并且其他新列的空值。

第3步:对扩展表进行分组和聚合。 我们需要按主机 ID 进行分组,因为它提供了 y 值:

create view history_itemvalue_pivot as (
  select
    hostid,
    sum(A) as A,
    sum(B) as B,
    sum(C) as C
  from history_extended
  group by hostid
);

select * from history_itemvalue_pivot;

+--------+------+------+------+
| hostid | A    | B    | C    |
+--------+------+------+------+
|      1 |   10 |    3 | NULL |
|      2 |    9 | NULL |   40 |
+--------+------+------+------+

(请注意,我们现在每个 y 值一行。) 好的,我们就快到了! 我们只需要摆脱那些丑陋的NULL

第四步:美化。 我们将用零替换任何空值,以便结果集看起来更好:

create view history_itemvalue_pivot_pretty as (
  select 
    hostid, 
    coalesce(A, 0) as A, 
    coalesce(B, 0) as B, 
    coalesce(C, 0) as C 
  from history_itemvalue_pivot 
);

select * from history_itemvalue_pivot_pretty;

+--------+------+------+------+
| hostid | A    | B    | C    |
+--------+------+------+------+
|      1 |   10 |    3 |    0 |
|      2 |    9 |    0 |   40 |
+--------+------+------+------+

我们就完成了——我们已经使用 MySQL 构建了一个漂亮的数据透视表。


应用此过程时的注意事项:

  • 在额外列中使用什么值。 在此示例中,我使用了 itemvalue
  • 在额外列中使用的“中性”值。 我使用了 NULL,但也可以是 0"",具体取决于您的具体情况,
  • 分组时使用什么聚合函数。 我使用了 sum,但是 countmax 也经常使用(max 经常在构建单行时使用) 使用多列
  • 作为 y 值。 此解决方案不限于对 y 值使用单个列 - 只需将额外的列插入 group by 子句(并且不要忘记 select他们)

已知的限制:

  • 此解决方案不允许数据透视表中有 n 列——扩展基表时需要手动添加每个数据透视列。 因此,对于 5 或​​ 10 个 x 值,此解决方案很好。 100块,不太好。 有一些使用存储过程生成查询的解决方案,但它们很丑陋并且很难正确执行。 当数据透视表需要有很多列时,我目前不知道有什么好方法来解决这个问题。

I'm going to add a somewhat longer and more detailed explanation of the steps to take to solve this problem. I apologize if it's too long.


I'll start out with the base you've given and use it to define a couple of terms that I'll use for the rest of this post. This will be the base table:

select * from history;

+--------+----------+-----------+
| hostid | itemname | itemvalue |
+--------+----------+-----------+
|      1 | A        |        10 |
|      1 | B        |         3 |
|      2 | A        |         9 |
|      2 | C        |        40 |
+--------+----------+-----------+

This will be our goal, the pretty pivot table:

select * from history_itemvalue_pivot;

+--------+------+------+------+
| hostid | A    | B    | C    |
+--------+------+------+------+
|      1 |   10 |    3 |    0 |
|      2 |    9 |    0 |   40 |
+--------+------+------+------+

Values in the history.hostid column will become y-values in the pivot table. Values in the history.itemname column will become x-values (for obvious reasons).


When I have to solve the problem of creating a pivot table, I tackle it using a three-step process (with an optional fourth step):

  1. select the columns of interest, i.e. y-values and x-values
  2. extend the base table with extra columns -- one for each x-value
  3. group and aggregate the extended table -- one group for each y-value
  4. (optional) prettify the aggregated table

Let's apply these steps to your problem and see what we get:

Step 1: select columns of interest. In the desired result, hostid provides the y-values and itemname provides the x-values.

Step 2: extend the base table with extra columns. We typically need one column per x-value. Recall that our x-value column is itemname:

create view history_extended as (
  select
    history.*,
    case when itemname = "A" then itemvalue end as A,
    case when itemname = "B" then itemvalue end as B,
    case when itemname = "C" then itemvalue end as C
  from history
);

select * from history_extended;

+--------+----------+-----------+------+------+------+
| hostid | itemname | itemvalue | A    | B    | C    |
+--------+----------+-----------+------+------+------+
|      1 | A        |        10 |   10 | NULL | NULL |
|      1 | B        |         3 | NULL |    3 | NULL |
|      2 | A        |         9 |    9 | NULL | NULL |
|      2 | C        |        40 | NULL | NULL |   40 |
+--------+----------+-----------+------+------+------+

Note that we didn't change the number of rows -- we just added extra columns. Also note the pattern of NULLs -- a row with itemname = "A" has a non-null value for new column A, and null values for the other new columns.

Step 3: group and aggregate the extended table. We need to group by hostid, since it provides the y-values:

create view history_itemvalue_pivot as (
  select
    hostid,
    sum(A) as A,
    sum(B) as B,
    sum(C) as C
  from history_extended
  group by hostid
);

select * from history_itemvalue_pivot;

+--------+------+------+------+
| hostid | A    | B    | C    |
+--------+------+------+------+
|      1 |   10 |    3 | NULL |
|      2 |    9 | NULL |   40 |
+--------+------+------+------+

(Note that we now have one row per y-value.) Okay, we're almost there! We just need to get rid of those ugly NULLs.

Step 4: prettify. We're just going to replace any null values with zeroes so the result set is nicer to look at:

create view history_itemvalue_pivot_pretty as (
  select 
    hostid, 
    coalesce(A, 0) as A, 
    coalesce(B, 0) as B, 
    coalesce(C, 0) as C 
  from history_itemvalue_pivot 
);

select * from history_itemvalue_pivot_pretty;

+--------+------+------+------+
| hostid | A    | B    | C    |
+--------+------+------+------+
|      1 |   10 |    3 |    0 |
|      2 |    9 |    0 |   40 |
+--------+------+------+------+

And we're done -- we've built a nice, pretty pivot table using MySQL.


Considerations when applying this procedure:

  • what value to use in the extra columns. I used itemvalue in this example
  • what "neutral" value to use in the extra columns. I used NULL, but it could also be 0 or "", depending on your exact situation
  • what aggregate function to use when grouping. I used sum, but count and max are also often used (max is often used when building one-row "objects" that had been spread across many rows)
  • using multiple columns for y-values. This solution isn't limited to using a single column for the y-values -- just plug the extra columns into the group by clause (and don't forget to select them)

Known limitations:

  • this solution doesn't allow n columns in the pivot table -- each pivot column needs to be manually added when extending the base table. So for 5 or 10 x-values, this solution is nice. For 100, not so nice. There are some solutions with stored procedures generating a query, but they're ugly and difficult to get right. I currently don't know of a good way to solve this problem when the pivot table needs to have lots of columns.
゛清羽墨安 2024-08-08 14:12:31

利用 Matt Fenwick 帮助我解决问题的想法(非常感谢),让我们将其减少到只有一个查询:

select
    history.*,
    coalesce(sum(case when itemname = "A" then itemvalue end), 0) as A,
    coalesce(sum(case when itemname = "B" then itemvalue end), 0) as B,
    coalesce(sum(case when itemname = "C" then itemvalue end), 0) as C
from history
group by hostid

Taking advantage of Matt Fenwick's idea that helped me to solve the problem (a lot of thanks), let's reduce it to only one query:

select
    history.*,
    coalesce(sum(case when itemname = "A" then itemvalue end), 0) as A,
    coalesce(sum(case when itemname = "B" then itemvalue end), 0) as B,
    coalesce(sum(case when itemname = "C" then itemvalue end), 0) as C
from history
group by hostid
﹎☆浅夏丿初晴 2024-08-08 14:12:31

我从子查询中编辑 Agung Sagita 的答案来加入。
我不确定这两种方式有多大区别,仅供参考。

SELECT  hostid, T2.VALUE AS A, T3.VALUE AS B, T4.VALUE AS C
FROM TableTest AS T1
LEFT JOIN TableTest T2 ON T2.hostid=T1.hostid AND T2.ITEMNAME='A'
LEFT JOIN TableTest T3 ON T3.hostid=T1.hostid AND T3.ITEMNAME='B'
LEFT JOIN TableTest T4 ON T4.hostid=T1.hostid AND T4.ITEMNAME='C'

I edit Agung Sagita's answer from subquery to join.
I'm not sure about how much difference between this 2 way, but just for another reference.

SELECT  hostid, T2.VALUE AS A, T3.VALUE AS B, T4.VALUE AS C
FROM TableTest AS T1
LEFT JOIN TableTest T2 ON T2.hostid=T1.hostid AND T2.ITEMNAME='A'
LEFT JOIN TableTest T3 ON T3.hostid=T1.hostid AND T3.ITEMNAME='B'
LEFT JOIN TableTest T4 ON T4.hostid=T1.hostid AND T4.ITEMNAME='C'
_失温 2024-08-08 14:12:31

使用子查询,

SELECT  hostid, 
    (SELECT VALUE FROM TableTest WHERE ITEMNAME='A' AND hostid = t1.hostid) AS A,
    (SELECT VALUE FROM TableTest WHERE ITEMNAME='B' AND hostid = t1.hostid) AS B,
    (SELECT VALUE FROM TableTest WHERE ITEMNAME='C' AND hostid = t1.hostid) AS C
FROM TableTest AS T1
GROUP BY hostid

但如果子查询结果超过一行,就会出现问题,在子查询中使用进一步的聚合函数

use subquery

SELECT  hostid, 
    (SELECT VALUE FROM TableTest WHERE ITEMNAME='A' AND hostid = t1.hostid) AS A,
    (SELECT VALUE FROM TableTest WHERE ITEMNAME='B' AND hostid = t1.hostid) AS B,
    (SELECT VALUE FROM TableTest WHERE ITEMNAME='C' AND hostid = t1.hostid) AS C
FROM TableTest AS T1
GROUP BY hostid

but it will be a problem if sub query resulting more than a row, use further aggregate function in the subquery

谁许谁一生繁华 2024-08-08 14:12:31

我的解决方案:

select h.hostid, sum(ifnull(h.A,0)) as A, sum(ifnull(h.B,0)) as B, sum(ifnull(h.C,0)) as  C from (
select
hostid,
case when itemName = 'A' then itemvalue end as A,
case when itemName = 'B' then itemvalue end as B,
case when itemName = 'C' then itemvalue end as C
  from history 
) h group by hostid

它在提交的案例中产生预期结果。

My solution :

select h.hostid, sum(ifnull(h.A,0)) as A, sum(ifnull(h.B,0)) as B, sum(ifnull(h.C,0)) as  C from (
select
hostid,
case when itemName = 'A' then itemvalue end as A,
case when itemName = 'B' then itemvalue end as B,
case when itemName = 'C' then itemvalue end as C
  from history 
) h group by hostid

It produces the expected results in the submitted case.

司马昭之心 2024-08-08 14:12:31

如果您可以使用 MariaDB 有一个非常非常简单的解决方案。

MariaDB-10.02 起,添加了一个名为 CONNECT< 的新存储引擎/a> 可以帮助我们将另一个查询或表的结果转换为数据透视表,就像您想要的那样:
您可以查看
文档

首先安装连接存储引擎

现在我们表的数据透视表列是 itemname 并且每个项目的数据位于 itemvalue 列中,因此我们可以使用此查询获得结果数据透视表:

create table pivot_table
engine=connect table_type=pivot tabname=history
option_list='PivotCol=itemname,FncCol=itemvalue';

现在我们可以从pivot_table中选择我们想要的内容:

select * from pivot_table

更多详细信息在这里

If you could use MariaDB there is a very very easy solution.

Since MariaDB-10.02 there has been added a new storage engine called CONNECT that can help us to convert the results of another query or table into a pivot table, just like what you want:
You can have a look at the docs.

First of all install the connect storage engine.

Now the pivot column of our table is itemname and the data for each item is located in itemvalue column, so we can have the result pivot table using this query:

create table pivot_table
engine=connect table_type=pivot tabname=history
option_list='PivotCol=itemname,FncCol=itemvalue';

Now we can select what we want from the pivot_table:

select * from pivot_table

More details here

萌化 2024-08-08 14:12:31

我将其放入 Group By hostId 中,然后它将仅显示带有值的第一行,
喜欢:

A   B  C
1  10
2      3

I make that into Group By hostId then it will show only first row with values,
like:

A   B  C
1  10
2      3
冰雪之触 2024-08-08 14:12:31

我找到了一种方法,可以使用简单的查询使我的报告将行转换为几乎动态的列。 您可以在此处在线查看并测试它。

查询的列数是固定的,但值是动态的并且基于行的值。 您可以构建它因此,我使用一个查询来构建表头,并使用另一个查询来查看值:

SELECT distinct concat('<th>',itemname,'</th>') as column_name_table_header FROM history order by 1;

SELECT
     hostid
    ,(case when itemname = (select distinct itemname from history a order by 1 limit 0,1) then itemvalue else '' end) as col1
    ,(case when itemname = (select distinct itemname from history a order by 1 limit 1,1) then itemvalue else '' end) as col2
    ,(case when itemname = (select distinct itemname from history a order by 1 limit 2,1) then itemvalue else '' end) as col3
    ,(case when itemname = (select distinct itemname from history a order by 1 limit 3,1) then itemvalue else '' end) as col4
FROM history order by 1;

您也可以对其进行总结:

SELECT
     hostid
    ,sum(case when itemname = (select distinct itemname from history a order by 1 limit 0,1) then itemvalue end) as A
    ,sum(case when itemname = (select distinct itemname from history a order by 1 limit 1,1) then itemvalue end) as B
    ,sum(case when itemname = (select distinct itemname from history a order by 1 limit 2,1) then itemvalue end) as C
FROM history group by hostid order by 1;
+--------+------+------+------+
| hostid | A    | B    | C    |
+--------+------+------+------+
|      1 |   10 |    3 | NULL |
|      2 |    9 | NULL |   40 |
+--------+------+------+------+

RexTester:

RexTester 结果

http://rextester. com/ZSWKS28923

作为一个真实的使用示例,下面的报告以列形式显示了船只/公共汽车的出发到达时间和可视时间表。 您将看到最后一列未使用的附加列,而不会混淆可视化:
sistema venda在线通道和最终消费者控制 - xsl tecnologia - xsl.com.br
** 票务系统在线售票和赠品

I figure out one way to make my reports converting rows to columns almost dynamic using simple querys. You can see and test it online here.

The number of columns of query is fixed but the values are dynamic and based on values of rows. You can build it So, I use one query to build the table header and another one to see the values:

SELECT distinct concat('<th>',itemname,'</th>') as column_name_table_header FROM history order by 1;

SELECT
     hostid
    ,(case when itemname = (select distinct itemname from history a order by 1 limit 0,1) then itemvalue else '' end) as col1
    ,(case when itemname = (select distinct itemname from history a order by 1 limit 1,1) then itemvalue else '' end) as col2
    ,(case when itemname = (select distinct itemname from history a order by 1 limit 2,1) then itemvalue else '' end) as col3
    ,(case when itemname = (select distinct itemname from history a order by 1 limit 3,1) then itemvalue else '' end) as col4
FROM history order by 1;

You can summarize it, too:

SELECT
     hostid
    ,sum(case when itemname = (select distinct itemname from history a order by 1 limit 0,1) then itemvalue end) as A
    ,sum(case when itemname = (select distinct itemname from history a order by 1 limit 1,1) then itemvalue end) as B
    ,sum(case when itemname = (select distinct itemname from history a order by 1 limit 2,1) then itemvalue end) as C
FROM history group by hostid order by 1;
+--------+------+------+------+
| hostid | A    | B    | C    |
+--------+------+------+------+
|      1 |   10 |    3 | NULL |
|      2 |    9 | NULL |   40 |
+--------+------+------+------+

Results of RexTester:

Results of RexTester

http://rextester.com/ZSWKS28923

For one real example of use, this report bellow show in columns the hours of departures arrivals of boat/bus with a visual schedule. You will see one additional column not used at the last col without confuse the visualization:
sistema venda de passagens online e consumidor final e controle de frota - xsl tecnologia - xsl.com.br
** ticketing system to of sell ticket online and presential

无人问我粥可暖 2024-08-08 14:12:31

这不是您正在寻找的确切答案,但这是我的项目所需的解决方案,希望这对某人有帮助。 这将列出 1 到 n 行项目,以逗号分隔。 Group_Concat 在 MySQL 中使这成为可能。

select
cemetery.cemetery_id as "Cemetery_ID",
GROUP_CONCAT(distinct(names.name)) as "Cemetery_Name",
cemetery.latitude as Latitude,
cemetery.longitude as Longitude,
c.Contact_Info,
d.Direction_Type,
d.Directions

    from cemetery
    left join cemetery_names on cemetery.cemetery_id = cemetery_names.cemetery_id 
    left join names on cemetery_names.name_id = names.name_id 
    left join cemetery_contact on cemetery.cemetery_id = cemetery_contact.cemetery_id 

    left join 
    (
        select 
            cemetery_contact.cemetery_id as cID,
            group_concat(contacts.name, char(32), phone.number) as Contact_Info

                from cemetery_contact
                left join contacts on cemetery_contact.contact_id = contacts.contact_id 
                left join phone on cemetery_contact.contact_id = phone.contact_id 

            group by cID
    )
    as c on c.cID = cemetery.cemetery_id


    left join
    (
        select 
            cemetery_id as dID, 
            group_concat(direction_type.direction_type) as Direction_Type,
            group_concat(directions.value , char(13), char(9)) as Directions

                from directions
                left join direction_type on directions.type = direction_type.direction_type_id

            group by dID


    )
    as d on d.dID  = cemetery.cemetery_id

group by Cemetery_ID

该墓地有两个通用名称,因此这些名称列在由单个 id 连接的不同行中,但有两个名称 id,查询会生成类似以下内容的内容

   CemeteryID    Cemetery_Name            纬度
   1               阿普尔顿,萨尔弗斯普林斯   35.4276242832293

This isn't the exact answer you are looking for but it was a solution that i needed on my project and hope this helps someone. This will list 1 to n row items separated by commas. Group_Concat makes this possible in MySQL.

select
cemetery.cemetery_id as "Cemetery_ID",
GROUP_CONCAT(distinct(names.name)) as "Cemetery_Name",
cemetery.latitude as Latitude,
cemetery.longitude as Longitude,
c.Contact_Info,
d.Direction_Type,
d.Directions

    from cemetery
    left join cemetery_names on cemetery.cemetery_id = cemetery_names.cemetery_id 
    left join names on cemetery_names.name_id = names.name_id 
    left join cemetery_contact on cemetery.cemetery_id = cemetery_contact.cemetery_id 

    left join 
    (
        select 
            cemetery_contact.cemetery_id as cID,
            group_concat(contacts.name, char(32), phone.number) as Contact_Info

                from cemetery_contact
                left join contacts on cemetery_contact.contact_id = contacts.contact_id 
                left join phone on cemetery_contact.contact_id = phone.contact_id 

            group by cID
    )
    as c on c.cID = cemetery.cemetery_id


    left join
    (
        select 
            cemetery_id as dID, 
            group_concat(direction_type.direction_type) as Direction_Type,
            group_concat(directions.value , char(13), char(9)) as Directions

                from directions
                left join direction_type on directions.type = direction_type.direction_type_id

            group by dID


    )
    as d on d.dID  = cemetery.cemetery_id

group by Cemetery_ID

This cemetery has two common names so the names are listed in different rows connected by a single id but two name ids and the query produces something like this


    CemeteryID     Cemetery_Name             Latitude

    1                    Appleton,Sulpher Springs   35.4276242832293

作妖 2024-08-08 14:12:31

我很抱歉这么说,也许我没有完全解决你的问题,但 PostgreSQL 比 MySQL 早 10 年,并且比 MySQL 更加先进,并且有很多方法可以轻松实现这一点。 安装 PostgreSQL 并执行此查询

CREATE EXTENSION tablefunc;

,然后瞧! 这里有大量文档: PostgreSQL: Documentation: 9.1: tablefunc 或此

CREATE EXTENSION hstore;

查询再次瞧! PostgreSQL:文档:9.0:hstore

I'm sorry to say this and maybe I'm not solving your problem exactly but PostgreSQL is 10 years older than MySQL and is extremely advanced compared to MySQL and there's many ways to achieve this easily. Install PostgreSQL and execute this query

CREATE EXTENSION tablefunc;

then voila! And here's extensive documentation: PostgreSQL: Documentation: 9.1: tablefunc or this query

CREATE EXTENSION hstore;

then again voila! PostgreSQL: Documentation: 9.0: hstore

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文