Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从MySQL中的行动态创建列_Mysql_Sql_Pivot_Crosstab - Fatal编程技术网

从MySQL中的行动态创建列

从MySQL中的行动态创建列,mysql,sql,pivot,crosstab,Mysql,Sql,Pivot,Crosstab,我有以下表格: "crawlresults" id | url | fk_crawljobs_id --------------------------------------------- 1 | shop*com/notebooks | 1 2 | shop*com/fridges | 1 3 | website*com/lists | 2 "extractions" id | fk_extracto

我有以下表格:

"crawlresults"
id  |   url                 | fk_crawljobs_id
---------------------------------------------
1   |   shop*com/notebooks  |   1
2   |   shop*com/fridges    |   1
3   |   website*com/lists   |   2


"extractions"
id  | fk_extractors_id  | data          |   fk_crawlresults_id
---------------------------------------------------------------
1   |   1               | 123.45        |   1
2   |   2               | notebook      |   1
3   |   3               | ibm.jpg       |   1
4   |   1               | 44.5          |   2
5   |   2               | fridge        |   2
6   |   3               | picture.jpg   |   3
7   |   4               | hello         |   3
8   |   4               | world         |   3
9   |   5               | hi            |   3
10  |   5               | my            |   3
11  |   5               | friend        |   3


"extractors"
id  |   extractorname
----------------------
1   |   price
2   |   article
3   |   imageurl
4   |   list_1
5   |   list_2
我需要构造一个select语句来获取提取器表中每个提取器的列,提取器表在提取器表中使用

例如:

url                 | price     | article   | imageurl
--------------------------------------------------------
shop*com/notebooks  | 123.45    | notebook  | ibm.jpg
shop*com/fridges    | 44.5      | fridge    | NULL
我不知道在执行select语句时存在多少extractornames,因此必须动态构建它

编辑: 我忘了提到在我的摘录中可能有多个“列表”。在这种情况下,我需要一个结果集

例2:

url                 | list_1    | imageurl      | list_2
--------------------------------------------------------
website*com/lists   | hello     | picture.jpg   | NULL
website*com/lists   | world     | picture.jpg   | NULL
website*com/lists   | NULL      | picture.jpg   | hello
website*com/lists   | NULL      | picture.jpg   | my
website*com/lists   | NULL      | picture.jpg   | friend
谢谢大家!

您正在寻找的

代码:


基本上,您最初的查询生成了一个虚假的
@sql
变量,它并没有真正为每个
提取名称提取
数据。创建
@sql
也不需要所有这些连接。您只需要每个属性名(来自
提取器
表)和对包含期望值的列的引用(
数据

当对结构有疑问时,为一组固定的属性编写一个简单的pivot查询。这样就很容易识别用于编写动态查询的模式

SELECT c.url, 
  MAX(IF(pa.extractorname = 'price', p.data, NULL)) AS price,
  MAX(IF(pa.extractorname = 'article', p.data, NULL)) AS article,
  MAX(IF(pa.extractorname = 'imageurl', p.data, NULL)) AS imageurl 
FROM crawlresults c 
  LEFT JOIN extractions p on (c.id = p.fk_crawlresults_id) 
  LEFT JOIN extractors pa on (p.fk_extractors_id = pa.id) 
WHERE c.fk_crawljobs_id = 1
GROUP BY c.id

至于查询的其余部分,这没关系,请记住,如果对某些
爬网结果
没有
提取,则
左连接可能很有用。另外,如果表中每个
url
/
fk\u crawljobs\u id
可以包含多个
crawlresult
,那么按
url
分组是个坏主意(
MAX
可能会混合多个
提取的结果)。

另一个类似的问题MySQL中没有pivot查询。事实上,这些类型的查询不属于数据库,因为它们的结果本身不是表;pivot转换属于数据库顶部的应用程序层。@Tomas,检查我的答案,你所需要的只是一个准备好的语句和一些爱。不需要将应用程序层放在下面:)。@AnthonyAccioly看起来不像执行pivot查询的好方法。我认为更可行的方法是在Java/PHP/ASP/C#/which中找到一些pivot转换库(类似于R中的
cast
函数-非常简单的用法)而不是一次又一次地调试一些复杂的SQL:-)@AnthonyAccioly我认为应用层正是它所属的地方。当我在提取器表中有一个额外的提取器名称,而该名称没有链接到提取器表中时,它仍然会成为结果集中的一列。另一个问题是当我有一个或多个提取列表时。我已经相应地编辑了我的问题。Jimbo,关于链接很简单,只需过滤与该查询()相关的
extractorname
,只需相应地更新创建
@sql
的子句即可。现在在多值行上重复单值结果。最后一把小提琴正是我所需要的。非常感谢!:-)
SELECT c.url, 
  MAX(IF(pa.extractorname = 'price', p.data, NULL)) AS price,
  MAX(IF(pa.extractorname = 'article', p.data, NULL)) AS article,
  MAX(IF(pa.extractorname = 'imageurl', p.data, NULL)) AS imageurl 
FROM crawlresults c 
  LEFT JOIN extractions p on (c.id = p.fk_crawlresults_id) 
  LEFT JOIN extractors pa on (p.fk_extractors_id = pa.id) 
WHERE c.fk_crawljobs_id = 1
GROUP BY c.id