简体   繁体   English

在 MySQL 中,如何从一个表中获取 2 列和从其他表中的一行中获取 2 行作为列?

[英]How to get 2 columns from one table and 2 rows as columns from other table in one row, in MySQL?

I know this is quite complicated, but I sincerely hope someone will check this out.我知道这很复杂,但我真诚地希望有人能检查一下。 I made short version (to better understand the problem) and full version (with original SQL)我制作了简短版本(以更好地理解问题)和完整版本(使用原始 SQL)

Short version:简短版本:

[TABLE A] [TABLE B]
|1|a|b|   |1|x
|2|c|d|   |1|y
|3| | |   |2|z
|5| | |   |2|v
          |4|w

How can I make MySQL query to get rows like that:我怎样才能让 MySQL 查询得到这样的行:

1|a|b|x|y
2|c|d|z|v

2 columns from A and 2 rows from B as columns, only with keys 1 and 2, no empty results A 的 2 列和 B 的 2 行作为列,只有键 1 和 2,没有空结果

Subquery?子查询?

Full version:完整版:

I tried to get from Prestashop db in one row :我试图在一行中从 Prestashop db 获取:

  • product id产品编号
  • ean13 code ean13 代码
  • upc code上行代码
  • feature with id 24 ID 为 24 的功能
  • feature with id 25 id 为 25 的特征

It's easy to get id_product, ean13 and upc, as it's one row in ps_product table. id_product、ean13 和 upc 很容易得到,因为它是 ps_product 表中的一行。 To get features I used subqueries (JOIN didn't work out).为了获得功能,我使用了子查询(JOIN 没有成功)。

So, I selected id_product, ean13, upc, (subquery1) as code1, (subquery2) as code2.所以,我选择了 id_product, ean13, upc, (subquery1) 作为 code1, (subquery2) 作为 code2。 Then I needed to throw out empty rows.然后我需要抛出空行。 But couldn't just put code1 or code2 in WHERE.但不能只将 code1 或 code2 放在 WHERE 中。 To make it work I had to put everything in subquery.为了使它工作,我必须将所有内容都放在子查询中。

This code WORKS , but it is terribly ugly and I bet this should be done differently.此代码的工作,但它是非常丑陋的,我敢打赌,这应该怎样做。

How can I make it BETTER?我怎样才能让它更好?

SELECT * FROM(
    SELECT 
        p.id_product as idp, p.ean13 as ean13, p.upc as upc, (
            SELECT
                fvl.value
            FROM
                `ps_feature_product` fp
            LEFT JOIN
                `ps_feature_value_lang` fvl ON (fp.id_feature_value = fvl.id_feature_value)
            WHERE fp.id_feature = 24 AND fp.id_product = idp
        ) AS code1, (
            SELECT
                fvl.value
            FROM
                `ps_feature_product` fp
            LEFT JOIN
                `ps_feature_value_lang` fvl ON (fp.id_feature_value = fvl.id_feature_value)
            WHERE fp.id_feature = 25 AND fp.id_product = idp
        ) AS code2,
        m.name
    FROM 
        `ps_product` p 
    LEFT JOIN 
        `ps_manufacturer` m ON (p.id_manufacturer = m.id_manufacturer)
) mainq
WHERE 
    ean13 != '' OR upc != '' OR code1 IS NOT NULL OR code2 IS NOT NULL
create table tablea 
( id int,
  col1 varchar(1),
  col2 varchar(1));

create table tableb 
( id int,
  feature int,
  cola varchar(1));

insert into tablea (id, col1, col2)
select 1,'a','b'  union
select 2,'c','d'  union
select 3,null,null  union
select 5,null,null;


insert into tableb (id, feature, cola)
select 1,24,'x'  union
select 1,25,'y' union
select 2,24,'z' union
select 2,25,'v' union
select 4,24,'w';

select a.id, a.col1, a.col2, b1.cola b1a, b2.cola b2a
from tablea a
inner join tableb b1 on (b1.id = a.id and b1.feature = 24)
inner join tableb b2 on (b2.id = a.id and b2.feature = 25);

SQLFiddle here . SQLFiddle在这里

What you want to do is called a Pivot Query .您想要做的称为Pivot Query MySQL has no native support for pivot queries, though other RDBMSen do. MySQL 没有对数据透视查询的原生支持,但其他 RDBMSen 支持。

You can simulate a pivot query with derived columns, but you must specify each derived column.您可以使用派生列模拟数据透视查询,但必须指定每个派生列。 That is, it is impossible in MySQL itself to have the number of columns match rows of another table.也就是说,MySQL 本身不可能让列数与另一个表的行匹配。 This has to be known ahead of time.这必须提前知道。

It would be much easier to query the results as rows and then use PHP to do the aggregation into columns.将结果作为行查询,然后使用 PHP 将其聚合到列中会容易得多。 For example:例如:

while ($row = $result->fetch()) {
    if (!isset($table[$row->id])) {
        $table[$row->id] = array();
    }
    $table[$row->id][] = $row->feature;

This is not a simple question because it's not a standard query, by the way if you can make use of views you can do the following procedure.这不是一个简单的问题,因为它不是标准查询,顺便说一下,如果您可以使用视图,则可以执行以下过程。 Assuming you're starting from this tables:假设你从这个表开始:

CREATE TABLE `A` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `firstA` char(1) NOT NULL DEFAULT '',
  `secondA` char(1) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
);

CREATE TABLE `B` (
  `id` int(11) unsigned NOT NULL,
  `firstB` char(1) NOT NULL DEFAULT ''
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `A` (`id`, `firstA`, `secondA`)
VALUES (1, 'a', 'b'), (2, 'c', 'd');

INSERT INTO `B` (`id`, `firstB`)
VALUES (1, 'x'), (1, 'y'), (2, 'z'), (2, 'v'), (4, 'w');

First create a view that joins the two tables:首先创建一个连接两个表的视图:

create or replace view C_join as
select A.firstA, A.secondA, B.firstB
from A
join B on B.id=A.id;

Create the view that groups the rows in table B:创建对表 B 中的行进行分组的视图:

create or replace view d_group_concat as
select firstA, secondA, group_concat(firstB) groupconcat
from c_join
group by firstA, secondA

Create the view that does what you need:创建执行您需要的视图:

create or replace view e_result as
select firstA, secondA, SUBSTRING_INDEX(groupconcat,',',1) firstB, SUBSTRING_INDEX(SUBSTRING_INDEX(groupconcat,',',2),',',-1) secondB
from d_group_concat

And that's all.仅此而已。 Hope this helps you.希望这对你有帮助。

If you can't create views, this could be the query:如果您无法创建视图,这可能是查询:

select firstA, secondA, SUBSTRING_INDEX(groupconcat,',',1) firstB, SUBSTRING_INDEX(SUBSTRING_INDEX(groupconcat,',',2),',',-1) secondB
from (
        select firstA, secondA, group_concat(firstB) groupconcat
        from (
                select A.firstA, A.secondA, B.firstB
                from A
                join B on B.id=A.id
        ) c_join
        group by firstA, secondA
) d_group_concat

Big thanks to everyone for the answers.非常感谢大家的回答。 James's answer was first, simplest and works perfectly in my case.詹姆斯的回答是第一个,最简单的,在我的情况下效果很好。 The query runs several times faster than mine, with subqueries.查询运行速度比我的快几倍,带有子查询。 Thanks, James!谢谢,詹姆斯!

Just a few words why I needed that:简单说一下为什么我需要它:

It's a part of integration component for Prestashop and wholesale exchange platform .它是 Prestashop 和批发交易平台的集成组件的一部分。 There are 4 product code systems that wholesalers use on the platform (ean13, upc and 2 other systems).平台上有 4 个批发商使用的产品代码系统(ean13、upc 和 2 个其他系统)。 Those 2 other product codes are added as product feature in Prestashop.这 2 个其他产品代码在 Prestashop 中作为产品功能添加。 There are thousands of products on the shop and hundreds of thousands of products on the platform .商店上有数千种产品,平台上有数十万种产品。 Which is why speed is crucial.这就是为什么速度至关重要。

Here is the code for full version of my question.这是我的问题的完整版本的代码。 Maybe someone will find this helpful.也许有人会发现这很有帮助。

Query to get Prestashop product codes and certain features in one row:查询以在一行中获取 Prestashop 产品代码和某些功能:

SELECT 
    p.id_product, p.ean13, p.upc, fvl1.value as code1, fvl2.value as code2
FROM `ps_product` p 
LEFT JOIN 
    `ps_feature_product` fp1 ON (p.id_product = fp1.id_product and fp1.id_feature = 24)
LEFT JOIN 
    `ps_feature_value_lang` fvl1 ON (fvl1.id_feature_value = fp1.id_feature_value)
LEFT JOIN 
    `ps_feature_product` fp2 ON (p.id_product = fp2.id_product and fp2.id_feature = 25)
LEFT JOIN 
    `ps_feature_value_lang` fvl2 ON (fvl2.id_feature_value = fp2.id_feature_value)
WHERE 
    ean13 != '' OR upc != '' OR fvl1.value IS NOT NULL OR fvl2.value IS NOT NULL;

暂无
暂无

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

相关问题 如何使用PHP或MySQL对一个表中的不同列求和,并在另一表中获得求和结果? - How to sum different columns from one table and get the sum result in another table using PHP or MySQL? [MySql]如何将一行从一个表复制到另一个表并填充额外的列? - [MySql]How to copy a row from one table to another and fill additional columns? 如何使用一行从同一mySQL表中提取其他多行 - How do I use one row to pull multiple other rows from the same mySQL table 将表B中的多行链接到MySQL中的表A中的一行 - Linking multiple rows from table B to one row in table A in MySQL MySQL-从一个表中获取所有匹配条件和关系的特定行(如果有的话)来自另一表 - Mysql - Get all specific rows from one table matching criteria and relations if any from other table 如何将一行从一个表移动到mysql中的另一个表? - How to move one row from one table, to another table in mysql? MySQL将具有特定列和UNIX时间戳的所有行从一个表复制到另一个表 - Mysql copy all rows from one table to another with specific columns and unix timestamp SQL将行从一个表移动到另一个表,具有不匹配的列 - SQL move row from one table to another with unmatched columns 使用Codeigniter将表中的一行与MySQL中其他两个表的多行联接 - Join one row from a table with multiple rows of two other tables in MySQL using Codeigniter 从一个表中选择一行,从另一表中选择多个行 - Select one row from one table and multiple rows from other table
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM