简体   繁体   English

SQL:获取在另一个表列中具有最大值但还与某些跨表子句匹配的项

[英]SQL: Getting items which have a max value in another tables column, but also match some cross table clauses

This is probably a really basic question but I have spend a lot of time on this. 这可能是一个非常基本的问题,但是我花了很多时间在这上面。

I have 2 Tables: 我有2张桌子:

Files

| FileId | Type | FolderId |
----------------------------
|   1    | txt  |    11    |
|   2    | xml  |    15    |
|   3    | xml  |    17    |
|   4    | txt  |    19    |

Folders 文件夹

| FolderId |   path    | version | typeId |        
-------------------------------------------     
| 11       | //c:/here | 1       |    1   | 
| 19       | //c:/here | 3       |    1   | 
| 15       | //c:/dummy| 6       |    1   | 
| 17       | //c:/dummy| 4       |    1   |

I want it to return: All info from Files , with the highest Folder.Version number, where the Files.type , Folders.path and Folders.typeID all match. 我希望它返回:来自Files所有信息,其中Folder.Version编号最高,其中Files.typeFolders.pathFolders.typeID都匹配。

Essentially I need to group by Files.type , where Folders.path & Folders.typeID are the same. 本质上,我需要按Files.type ,其中Folders.pathFolders.typeID相同。 Then return the item with the max version field for each group. 然后返回每个组的“最大版本”字段的项目。

So in the example above I would want the output: 因此,在上面的示例中,我需要输出:

| FileId | Type | FolderId |
----------------------------
|   2    | xml  |    15    |
|   4    | txt  |    19    |

So far I have the query below, which I think is ok for getting the items with the highest version number when TypeId and path match (I think????). 到目前为止,我有下面的查询,我认为可以在TypeId和path匹配时获取具有最高版本号的项目(我认为吗???)。 But I cannot figure out how to group by Files.Type. 但我不知道如何按Files.Type进行分组。

SELECT * FROM Files
WHERE FileId IN (
  SELECT FileId   FROM Files
  WHERE FolderId IN (  
    SELECT fo.FolderId                   
    FROM Folders fo                
    LEFT JOIN Folders fo2      
        ON fo.Path = fo2.Path AND fo.TypeId = fo2.TypeId    
        AND fo.Version < fo2.Version            
    WHERE fo2.Version IS NULL
  )
)

Can anyone explain how I can get this query done? 谁能解释我如何完成此查询? I have a feeling I need some group by statements but I can't figure it out! 我觉得我需要一些总结,但我无法弄清楚!

This is SQL server 2012. 这是SQL Server 2012。

You didn't specify a verson of SQL Server. 您没有指定SQL Server的版本。

select Files.*
from
    Files inner join
    (
        select f1.FolderId
        from Folders f1 inner join
            (
                select TypeId, Path, max(Version) as MaxVersion
                from Folders
                group TypeId, Path
            ) as f2
            on f2.TypeId = f1.TypeId and f2.Path = f1.Path f2.MaxVersion = f1.Version
    ) Folders
        on Folders.FolderId = Files.FolderId

If you have a later edition of SQL Server then this should work too: 如果您有更高版本的SQL Server,那么它也应该起作用:

select Files.*
from
    Files inner join
    (
        select first_value(FolderId)
            over (partition by TypeId, Path order by Version desc) as FolderId
        from Folders
    ) Folders
        on Folders.FolderId = Files.FolderId

EDIT: Maybe this is the fix per your comment: 编辑:也许这是根据您的评论的修复程序:

select Files.*
from
    Files fi inner join Folders fo on fo.FolderId = fi.FolderId
    inner join
    (
        select "Type", TypeId, Path, max(Version) as MaxVersion
        from Files fi2 inner join Folders fo2 on fo2.FolderId = fi2.FolderId
        group "Type", TypeId, Path
    ) as mv
        on      mv."Type" = fi."Type"
            and mv.TypeId = fo.TypeId and mv.Path = fo.Path
            and mv.MaxVersion = fo.Version

I'm in a rush but I think this might work on SQL Server 2012: 我很着急,但我认为这可能适用于SQL Server 2012:

select distinct
    first_value(FileId)
        over (partition by "Type", TypeId, Path order by Version desc) as FileId,
    "Type",
    first_value(fo.FolderId)
        over (partition by "Type", TypeId, Path order by Version desc) as FolderId
from
    Files fi inner join Folders fo on fo.FolderId = fi.FolderId

Give this a shot: 试一下:

select f.*
from files f
inner join folders dir on f.folderid = dir.folderid
inner join (
  select type, max(version) maxver
  from files fi
  inner join folders fo on fi.folderid = fo.folderid
  group by type
) t on f.type = t.type and dir.version = t.maxver

Result: 结果:

| fileid | type | folderid |
|--------|------|----------|
|      4 |  txt |       19 |
|      2 |  xml |       15 |

Since SQLFiddle SQL Server 2008 and 2014 were not responding well, I created an example with MySQL here: http://sqlfiddle.com/#!9/7abd4/13 . 由于SQLFiddle SQL Server 2008和2014的响应不佳,因此我在此处使用MySQL创建了一个示例: http ://sqlfiddle.com/#!9/7abd4/13。 I expect the query results to be identical for SQL Server 2012. 我希望查询结果对于SQL Server 2012是相同的。

Simple top-1-per-group, isn't it? 简单的每组前1名,不是吗?

One possible variant using ROW_NUMBER . 一种使用ROW_NUMBER可能变体。

PARTITION BY Files.Type, Folders.path, Folders.typeId define the groups, ORDER BY Folders.version DESC define which row to pick for each group. PARTITION BY Files.Type, Folders.path, Folders.typeId定义组, ORDER BY Folders.version DESC定义为每个组选择哪一行。

More efficient than self-join. 比自我加入更有效。

WITH
CTE AS
(
    SELECT
        Files.FileId
        ,Files.Type
        ,Files.FolderId
        ,Folders.path
        ,Folders.typeId
        ,Folders.version
        ,ROW_NUMBER() OVER (
            PARTITION BY Files.Type, Folders.path, Folders.typeId 
            ORDER BY Folders.version DESC) AS rn
    FROM
        Files
        INNER JOIN Folders ON Folders.FolderId = Files.FolderId
)
SELECT *
FROM CTE
WHERE rn = 1
;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 SQL查询以从一列中获取最大值,但也保留不属于pf group by的另一列 - SQL query to get max from a column but also keeping another column which is not part pf group by 计算表中匹配的Sql中两列值对 - Count pair of two column value in Sql which are match in tables SQL选择两个彼此关联的表 - SQL select two tables which have relationship with one another table SQL:根据其ID从表中删除项目,该ID也出现在另一个表中 - SQL: delete items from table based on their ID, which also appears in another table 更新 SQL 服务器中的列,而另一个表中某些列的值存在差异 - Updating a column in SQL Server with difference in value of some column in another table 为另一列的每个不同值获取具有该列最大值的行 - Fetch the rows which have the Max value for a column for each distinct value of another column Sql在另一列的同一表中具有相同值的项目 - Sql group items with same value in same table in another column 查询以获取一个表的值,该值不在另一表的字符串列中,还小于特定的日期时间值 - Query to get values of one table which are not there in string column of another table, also less than a particular datetime value SQL:如果条件不匹配(表中的行),则返回默认值和从不同表匹配的行 - SQL: If there is No match on condition (row in table) return a default value and Rows which match from different tables SQL在第二个表中加入2个表,其中“最大值”为“ON” - SQL Join 2 tables with “ON” on max value in second table
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM