您好我正在寻找以下自我反身交叉连接的替代语法。目标是一种表格的行填充 - 日期应该包含每个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
我尝试使用简单别名重新构建交叉连接,但这会在连接中出现列错误。是可以这样做还是我应该考虑使用视图呢?
因为交叉连接应该简单地返回两个表的笛卡尔积,它应该与没有连接时简单地选择它们相同。但是,以下内容引发了“未知列d.labelDate in on clause”异常
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
Error Code: 1054. Unknown column 'd.cdn' in 'on clause'
由于d
和n
的长度相对较小,因此查询的大小足够快。
答案 0 :(得分:0)
我认为你的原意很接近......对于每个日期,你都需要每个网络节点状态的结果。如果在没有连接条件的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
答案 1 :(得分:0)
根据lableDate
和x - cdn
以及值sites
,假设cdn
的值为(a),请阅读评论和额外信息,您需要使用y - sites
和x - 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
和值labelDate cdn_a cdn_b cdn_c
2013-04 NULL 5 4
2013-05 6 NULL NULL
....
,b,c)并且{{1}}是一个可以尝试的数字:
{{1}}
输出应该是这样的(我使用了你的样本数据):
{{1}}
答案 2 :(得分:0)
经过一番游戏,这是我能想到的最好的。似乎可以对表名进行参数化,但是会涉及另一层语句生成,幸运的是,这个项目并不需要。
-- --------------------------------------------------------------------------------
-- 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
这可以简单地称为e。,g。
call cdn_pivot('Top100', '2013-01-01', 2013-02-01')
考虑到与测试此代码并将其保留在任何客户端代码相关的问题,在客户端生成头部的动态部分非常诱人,至少对于这种用例,性能损失是额外的查询不应该太高。关键是显然要了解如何动态生成列。