Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/58.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 - Fatal编程技术网

Mysql 创建自反射交叉联接

Mysql 创建自反射交叉联接,mysql,sql,Mysql,Sql,嗨,我想看看下面的自反射交叉连接是否有其他语法。目标是一种表格的行填充器-每个cdn的日期都应该有条目。我正在使用MySQL select d.labelDate, n.cdn, networks.sites from ( select distinct labelDate from cdn_trend ) as d cross join ( select distinct cdn from cdn_trend ) as n le

嗨,我想看看下面的自反射交叉连接是否有其他语法。目标是一种表格的行填充器-每个cdn的日期都应该有条目。我正在使用MySQL

select 
  d.labelDate, 
  n.cdn,
  networks.sites
from (
  select 
    distinct labelDate 
  from 
    cdn_trend
) as d
cross join (
  select 
    distinct cdn 
  from cdn_trend
) as n
left join cdn_trend as networks 
  on  networks.labelDate = d.labelDate
  and networks.cdn = n.cdn    
order by 
  labelDate, 
  cdn
我曾尝试使用简单的别名重新构建交叉连接,但这会导致连接中出现列错误。是否有可能这样做呢?还是应该考虑使用视图?< /P> 由于交叉联接应该只返回两个表的笛卡尔积,因此它应该与只选择两个表而不进行联接相同。但是,以下内容引发了“on子句中的未知列d.labelDate”异常

select distinct d.labelDate, n.cdn, networks.sites
from 
cdn_trend as d,
cdn_trend as n
left join cdn_trend as networks ON
(n.labelDate = networks.labelDate
and d.cdn = networks.cdn)
order by labelDate, cdn
错误代码:1054。“on子句”中的未知列“d.cdn”


因为
d
n
的长度相对较小,所以查询的大小足够快。

我认为您的初衷很接近。。。对于每个日期,您都需要每个网络节点状态的结果。如果在WHERE子句中列出多个表而没有连接条件,则默认情况下,它将创建笛卡尔。。。从此,连接到您的详细信息表

select 
      d.labelDate, 
      n.cdn,
      networks.sites
   from 
      ( select d.LabelDate, n.cdn
           from 
              ( select distinct labelDate 
                   from cdn_trend ) as d,
              ( select distinct cdn 
                   from cdn_trend ) as n ) as CrossResults
         LEFT JOIN cdn_trend as networks 
         on  CrossResults.labelDate = networks.labelDate
         and CrossResults.cdn = networks.cdn
   order by 
      networks.labelDate, 
      networks.cdn

阅读评论和额外信息时,您需要一个带有y-
lableDate
和x-
cdn
和值的轴心,假设
cdn
的值是(a、b、c),并且
站点
是一个数字,您可以尝试以下方法:

SELECT
    labelDate,
    SUM(IF(cdn = 'a',sites,0)) as cdn_a,
    SUM(IF(cdn = 'b',sites,0)) as cdn_b,
    SUM(IF(cdn = 'c',sites,0)) as cdn_c
FROM 
    cdn_trend
GROUP BY
    labelDate
输出应该是这样的(我使用了您提供的示例数据):


在玩了一番之后,这是我能想到的最好的了。表名的参数化似乎是可能的,但会涉及到另一层语句生成,幸运的是,我不需要这个项目

-- --------------------------------------------------------------------------------
-- Routine DDL
-- Note: comments before and after the routine body will not be stored by the server
-- --------------------------------------------------------------------------------
DELIMITER $$

CREATE DEFINER="root"@"localhost" PROCEDURE "cdn_pivot"(
    IN slice varchar(64),
    IN start date,
    IN stop date)

BEGIN

SET @@group_concat_max_len = 32000;
SET @sql = NULL;

SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
    ' sum(IF(cdn = ''',
        cdn,
        ''', sites,NULL)) "'
        ,cdn, '"'
    )
  ) INTO @sql
FROM cdns ORDER BY sites;

SET @stmt = CONCAT('SELECT labelDate, ',
@sql,
' from cdns 
WHERE slice = ''',
slice,
''' AND ( labelDate between''',
start,
''' AND ''',
stop,
'''
) 
GROUP BY labelDate');

prepare stmt from @stmt;
execute stmt;
deallocate prepare stmt;

SET @@group_concat_max_len = 1024;
END
这可以简单地称为,例如。
呼叫cdn\u pivot('Top100','2013-01-01',2013-02-01')


考虑到测试此代码并将其与任何客户端代码一起保存的相关问题,在客户端生成头部的动态部分是非常诱人的,至少对于这种用例,额外查询的性能损失不应该太高。很明显,关键是理解如何动态生成列。

这是非常低效的。。。这样做的目的是什么?要删除未设置日期的条目?我看不出左侧外部联接在做什么。在查询中不使用别名“networks”中的任何内容,但加入它们的位置除外。我也会尽量不做次选择,但也许你需要。如果没有更多的上下文,很难说。@Stephan查询的目的是为每个时间段返回相同数量的行。例如:2013-05可能有
('a','c')
,2013-04可能有
('b','c')
。我希望行中有
2013-04,'a',NULL
2013-04,'b',5
2013-04,'c',4
2013-05,'a',6
2013-05,'b',NULL
2013-06,'c',7
网络。网站@MarkBannister感谢你发现了打字错误,因为我太忙了,没有时间检查所有内容。我已更正并添加了错误消息。这似乎表明针对两个表的左连接是不可能的,但如果我将其作为两个单独的左连接来编写,则无法获得所需的结果,并且查询速度明显较慢。谢谢,但这仍然会引发相同的错误。然而,我认为解决方案实际上是生成一个数据透视表,因为这正是我想要的:一个
labelDate
by
cdn
矩阵,其中
站点
Null
作为值。我认为有必要通过一个有序的结果集,比如我的查询生成的结果集,但事实似乎并非如此。现在我只需要编写创建列的函数。是的,这就是我正在努力的方向。有没有办法创建一个函数/过程来在查询头中生成这些列?我一直在看,但还没有创建一些可以生成并运行查询或只是返回列的东西?您可以从代码端执行。。。使用将生成此查询的脚本。基本上,您需要
cdn
字段的不同值来生成pivot。当然,我知道如何在客户端代码中生成查询。我只是想有一个更通用的方法。我想我可以对用户定义的函数做同样的事情?是的,你可以有一个更通用的方法,比如创建一个有输入的方法:field_x(在你的情况下是labelDate)、field_y(在你的情况下是cdn)、field_值(在你的情况下是sites)、table_name(cdn_趋势)。我不确定是否可以使用UDF,但您可以尝试。作为一个简单的函数,它似乎可以很好地工作,但不是作为一个过程。但我怀疑这与不太了解这一切是如何运作的有很大关系。我现在已经成功地协商了所有的
OUT
s和
IN
s程序,包括
GROUP_CONCAT的长度限制
-- --------------------------------------------------------------------------------
-- Routine DDL
-- Note: comments before and after the routine body will not be stored by the server
-- --------------------------------------------------------------------------------
DELIMITER $$

CREATE DEFINER="root"@"localhost" PROCEDURE "cdn_pivot"(
    IN slice varchar(64),
    IN start date,
    IN stop date)

BEGIN

SET @@group_concat_max_len = 32000;
SET @sql = NULL;

SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
    ' sum(IF(cdn = ''',
        cdn,
        ''', sites,NULL)) "'
        ,cdn, '"'
    )
  ) INTO @sql
FROM cdns ORDER BY sites;

SET @stmt = CONCAT('SELECT labelDate, ',
@sql,
' from cdns 
WHERE slice = ''',
slice,
''' AND ( labelDate between''',
start,
''' AND ''',
stop,
'''
) 
GROUP BY labelDate');

prepare stmt from @stmt;
execute stmt;
deallocate prepare stmt;

SET @@group_concat_max_len = 1024;
END