加入还是SubQuery?

时间:2016-01-13 12:06:50

标签: mysql join subquery correlated-subquery

我有一个MySQL表,记录了各种网站上使用的插件标题,包括版本号。例如:

    AddonName | Website ID | Version

    ZZZ         1           3.3
    ZZZ         2           3.4
    ZZZ         3           3.4
    ZZZ         4           3.1
    YYY         1           1.1
    YYY         2           1.1
    YYY         3           1.1
    YYY         4           1.2

我想创建一个列出不同AddonName列表的查询,其中包含总计数的详细信息,使用最新版本的所有网站的数量以及使用过期版本的所有网站的计数。

即:

    Name | Total Addons | Up to Date | Out of Date
    ZZZ    4              2            2
    YYY    4              1            3

我无法弄清楚如何返回这种类型的数据,即使信息全部存在。我尝试使用JOIN查询,但没有任何成功。

如果它有助于简化操作,我可以在表格中添加“最新”枚举字段,以便在导入时将行标记为最新或过时。

6 个答案:

答案 0 :(得分:2)

假设最大值为最新版本。

试试这个:

select t1.AddonName,
count(*) as total_Addon,
sum(case when t1.version=t2.version then 1 else 0 end) as up_to_date,
sum(case when t1.version!=t2.version then 1 else 0 end) as out_of_date
from table1 t1
inner join(
  select AddonName,max(version) as version
  from table1 group by AddonName
)t2 on t1.AddonName=t2.AddonName 
group by t1.AddonName

答案 1 :(得分:1)

尝试:

SELECT your_table.AddonName,
   COUNT(`Website ID`),
   COUNT(IF(Version = your_table_max.max_version, 1, NULL)) AS `Up to Date`,
   COUNT(IF(Version <> your_table_max.max_version, 1, NULL)) AS `Out of Date`
  FROM your_table
    INNER JOIN (SELECT MAX(Version) as max_version, AddonName
                  FROM your_table group by AddonName) your_table_max
    ON your_table_max.AddonName = your_table.AddonName
  GROUP BY your_table.AddonName;

答案 2 :(得分:1)

假设最新版本来自最后一栏:

select t.name, count(*) as TotalAddons,
       sum(t.version = tt.maxv) as UpToDate,
       sum(t.version <> tt.maxv) as OutOfDate
from t join
     (select name, max(version) as maxv
      from t
      group by name
     ) tt
     on t.name = tt.name
group by t.name;

这将计算子查询中每个名称的最大版本号。然后,它将该信息用于外部聚合。

这假定版本是一个数字。如果它是一个字符串(所以1.10> 1.2),那么类似的方法是:

select t.name, count(*) as TotalAddons,
       sum(t.version = t.maxv) as UpToDate,
       sum(t.version <> t.maxv) as OutOfDate
from (select t.*,
             (select version
              from t t2
              where t2.name = t.name
              order by length(version) desc, version desc
              limit 1
             ) as maxv
      from t
     ) t
group by t.name;

当然,这也适用于数字。

答案 3 :(得分:1)

试试这个会解决你的问题。

select AddonName,count(AddonName) as countAdd,(select count(Version)from test1 as t where  t.AddonName = test1.AddonName and t.Version = max(test1.Version)),(select count(Version) from test1 as t where t.AddonName = test1.AddonName and t.Version = min(test1.Version))from test1 GROUP BY AddonName;

答案 4 :(得分:0)

添加Latest表后,请尝试按照(插入表名后)

select 
  AddonName as Name, 
  count(*) as TotalAddons,
  count(case TableName.Version when Latest.LatestVersion 
    then 1 else null end) as UpToDate,
  TotalAddons-UpToDate as OutOfDate

from TableName join Latest 
  on TableName.AddonName = Latest.AddonName 
group by AddonName

答案 5 :(得分:0)

WITH cte
AS
(
    SELECT t.AddonName, MAX(t.Version) AS latest_version 
    FROM Table1 t 
    GROUP BY t.AddonName 
)
SELECT t.AddonName, COUNT(t.WebsiteID) AS total_addons,
SUM
(
    CASE WHEN t.version = cte.latest_version 
    THEN 1 ELSE 0 END
) AS up_to_date,
SUM
(
    CASE WHEN t.version <> cte.latest_version 
    THEN 1 ELSE 0 END
) AS out_of_date
FROM Table1 t 
JOIN cte ON t.AddonName = cte.AddonName 
GROUP BY t.AddonName