SQL Server-仅在所有子项可用时返回项目

时间:2017-01-28 16:22:15

标签: sql sql-server sql-server-2016

我有一个Item表(在这个例子中是非规范化的),包含一个项目列表,零件以及该零件是否可用。我想要退回所有可用部件的所有物品。每个项目可以具有不同数量的部件。例如:

Item   Part   Available
 A      1      Y
 A      2      N
 A      3      N
 B      1      Y
 B      4      Y
 C      2      N
 C      5      Y
 D      4      Y
 D      6      Y
 D      7      Y

查询应返回以下内容:

Item  Part
 B     1
 B     4
 D     4    
 D     6    
 D     7    

提前感谢您的任何帮助。

6 个答案:

答案 0 :(得分:0)

以下是使用Max() Over()窗口聚合函数

的一个技巧
SELECT Item,
       Part
FROM   (SELECT Max([Available])OVER(partition BY [Item]) m_av,*
        FROM   yourtable) a
WHERE  m_av = 'Y' 

或使用Group ByHaving子句

使用IN子句

SELECT Item,
       Part
FROM   yourtable
WHERE  Item IN (SELECT Item
                FROM   yourtable
                GROUP  BY Item
                HAVING Count(*) = Sum(Iif(Available = 'Y', 1, 0)))

使用Exists

SELECT Item,
       Part
FROM   yourtable A
WHERE  EXISTS (SELECT 1
               FROM   yourtable B
               WHERE  A.Item = B.Item
               HAVING Count(*) = Sum(Iif(Available = 'Y', 1, 0))) 

使用NOT EXISTS

SELECT Item,
       Part
FROM   yourtable A
WHERE  NOT EXISTS (SELECT *
                   FROM   yourtable B
                   WHERE  A.Item = B.Item
                          AND B.Available = 'N') 

答案 1 :(得分:0)

我首先要重新说明要求 - 您想要退回没有任何不可用部分的商品。一旦你这样说,使用not exists运算符将需求转换为SQL很容易:

SELECT item, part
FROM   parts a
WHERE  NOT EXISTS (SELECT *
                   FROM   parts b
                   WHERE  a.item = b.item AND b.available = 'N')

答案 2 :(得分:0)

您可以使用NOT INNOT EXISTS来实现此目标

NOT EXISTS

Select item, part 
from table as T1 
where not exists( select 1 from tbl where item = t1.item and available = 'N')

不在

Select item, part 
from table 
where item not in( select item from tbl where available = 'N')

答案 3 :(得分:0)

使用窗口函数可以读取单个表格。

'use strict';
angular.module('himerosApp')
.controller("ProductController", ['$scope','messages',
function($scope, messages ) {

    $scope.products = messages;

}]);

'use strict'; angular.module('himerosApp') .controller("ProductController", ['$scope','messages', function($scope, messages ) { $scope.products = messages; }]); 窗口函数

angular.module('himerosApp')
.service("productService",['$http','$q',
 function( $http, $q ) {

    this.getProducts = function() {

        return $http.get("/products").then(
            function( response ) {
                return response.data;
            },
            function( response ) {

                if(!angular.isObject( response.data ) ) {
                    console.log('unknown error');
                    return ( $q.reject( "An unknown error ocurred." ) );
                }       

                console.log(response.data.message);
                return ( $q.reject( response.data.message ) );
            }
        );
    };

    return {
        getProducts : this.getProducts
    };
}]);

angular.module('himerosApp') .service("productService",['$http','$q', function( $http, $q ) { this.getProducts = function() { return $http.get("/products").then( function( response ) { return response.data; }, function( response ) { if(!angular.isObject( response.data ) ) { console.log('unknown error'); return ( $q.reject( "An unknown error ocurred." ) ); } console.log(response.data.message); return ( $q.reject( response.data.message ) ); } ); }; return { getProducts : this.getProducts }; }]); 窗口函数:

MIN

答案 4 :(得分:0)

我想指出的是,文中的问题是:“我想要归还所有部件都可用的所有物品”。但是,您的示例结果包括部分。

如果问题确实只是你想要的项目,那么你可以使用简单的聚合:

select item
from parts 
group by item
having min(available) = max(available) and min(available) = 'Y';

如果你确实想要部件的细节,那么其他答案就会提供这些信息。

答案 5 :(得分:0)

我确实喜欢这个问题很适合通过不经常使用的语言功能解决:

with cte as (
    select * from (values
        ('A', 1, 'Y'),
        ('A', 2, 'N'),
        ('A', 3, 'N'),
        ('B', 1, 'Y'),
        ('B', 4, 'Y'),
        ('C', 2, 'N'),
        ('C', 5, 'Y'),
        ('D', 4, 'Y'),
        ('D', 6, 'Y'),
        ('D', 7, 'Y')
    ) as x(Item, Part, Available)
)
select *
into #t
from cte as c;

select *
from #t as c
where 'Y' = all (
    select Available
    from #t as a
    where c.Item = a.Item
) 

在这里,我们使用相关子查询和all关键字来查看是否所有部分都可用。我的理解是,就像exists一样,如果它找到一个反例,它就会停止。