如何将这两个查询合并为一个?

时间:2011-11-15 17:12:37

标签: mysql

我有两个表,一个用于下载,一个用于上传。它们几乎完全相同,但有一些其他列不同。我想为表格中的每个项目生成每个日期的统计信息列表。

我使用这两个查询但是在运行它们之后必须合并php中的数据。我想在一个查询中运行它们,它将从按日期分组的每一行中的两个查询中返回列。有时没有任何下载数据,只有上传数据,而且在以前的所有尝试中,如果它无法从两行中找到日志数据,它会跳过该行。

如何将这两个查询合并为一个,即使它在其中一个表中可用,它也会显示数据?

SELECT DATE(upload_date_added) as upload_date, SUM(upload_size) as upload_traffic, SUM(upload_files) as upload_files
FROM packages_uploads
WHERE upload_date_added BETWEEN '2011-10-26' AND '2011-11-16'
GROUP BY upload_date
ORDER BY upload_date DESC


SELECT DATE(download_date_added) as download_date, SUM(download_size) as download_traffic, SUM(download_files) as download_files
FROM packages_downloads
WHERE download_date_added BETWEEN '2011-10-26' AND '2011-11-16'
GROUP BY download_date
ORDER BY download_date DESC

我想获得这样的结果行:

date,upload_traffic,upload_files,download_traffic,download_files

所有帮助表示赞赏!

4 个答案:

答案 0 :(得分:1)

您可以执行两个查询,然后将其与UNION子句以及一个额外字段结合使用,以在不同的行上标识上载和下载:

SELECT
    'Uploads' TransmissionType,
    DATE(upload_date_added) as TransmissionDate,
    SUM(upload_size) as TransmissionTraffic,
    SUM(upload_files) as TransmittedFileCount
FROM
    packages_uploads 
WHERE upload_date_added BETWEEN '2011-10-26' AND '2011-11-16' 
GROUP BY upload_date 
ORDER BY upload_date DESC 
UNION 
SELECT
    'Downloads',
    DATE(download_date_added),
    SUM(download_size),
    SUM(download_files) 
FROM packages_downloads 
WHERE download_date_added BETWEEN '2011-10-26' AND '2011-11-16' 
GROUP BY download_date 
ORDER BY download_date DESC;

试一试!!!

答案 1 :(得分:0)

您所询问的内容仅适用于具有相同的上传和下载添加日期的行。在这种情况下,我认为这个SQL应该有效:

SELECT 
    DATE(u.upload_date_added) as date,
    SUM(u.upload_size) as upload_traffic,
    SUM(u.upload_files) as upload_files,
    SUM(d.download_size) as download_traffic,
    SUM(d.download_files) as download_files
FROM 
    packages_uploads u, packages_downloads d
WHERE u.upload_date_added = d.download_date_added
AND u.upload_date_added BETWEEN '2011-10-26' AND '2011-11-16'
GROUP BY date
ORDER BY date DESC

答案 2 :(得分:0)

如果不知道架构很难给出确切的答案,请将以下内容视为概念而非直接答案。

你可以尝试左连接,我不确定表包是否存在,但以下可能是值得深思的

SELECT 
  p.id,  
  up.date as upload_date
  dwn.date as download_date
FROM 
package p
LEFT JOIN package_uploads up ON 
    ( up.package_id = p.id WHERE up.upload_date = 'etc' )
LEFT JOIN package_downloads dwn ON 
    ( dwn.package_id = p.id WHERE up.upload_date = 'etc' )

以上将选择所有包并尝试加入,并且值不加入的位置将返回null。

答案 3 :(得分:0)

有很多方法可以做到这一点。您可以使用主键和外键加入。如果表之间没有关系,

您可以使用,

  • LEFT JOIN / LEFT OUTER JOIN
  

返回左表中匹配的所有记录   右表中的记录。结果是来自NULL   当没有比赛时右侧。

  • RIGHT JOIN / RIGHT OUTER JOIN
  

返回右表和匹配的所有记录   左表中的记录。结果是左侧NULL   当没有比赛的时候。

  • FULL OUTER JOIN
  

当左表或右表记录中存在匹配时,返回所有记录。

  • UNION
  

用于组合两个或多个SELECT语句的结果集。

     

SELECT中的每个UNION语句必须具有相同的数量,   columns列还必须具有相似的数据类型列中,   每个SELECT语句也必须采用相同的顺序。

  • INNER JOIN
  

选择两个表中具有匹配值的记录。 - 这对你的情况有好处。

  • INTERSECT
  

不支持MySQL。

  • NATURAL JOIN
  

应匹配所有列名称。

由于您不需要更新这些,您可以从连接表创建view,然后您可以在PHP中使用较少的查询。但观点无法更新。你没有提到表之间的关系。因此,我必须使用UNION

像这样,

CREATE VIEW checkStatus
AS
SELECT 
    DATE(upload_date_added) as upload_date,
    SUM(upload_size) as upload_traffic,
    SUM(upload_files) as upload_files
FROM packages_uploads
WHERE upload_date_added BETWEEN '2011-10-26' AND '2011-11-16'
GROUP BY upload_date
ORDER BY upload_date DESC

UNION

SELECT 
    DATE(download_date_added) as download_date,
    SUM(download_size) as download_traffic,
    SUM(download_files) as download_files
FROM packages_downloads
WHERE download_date_added BETWEEN '2011-10-26' AND '2011-11-16'
GROUP BY download_date
ORDER BY download_date DESC

然后,您想要选择的任何地方只需要一行:

SELECT * FROM checkStatus

learn more