Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 选择与列表中所有项目匹配的行组_Sql_Sql Server_Tsql_Relational Division - Fatal编程技术网

Sql 选择与列表中所有项目匹配的行组

Sql 选择与列表中所有项目匹配的行组,sql,sql-server,tsql,relational-division,Sql,Sql Server,Tsql,Relational Division,假设我有两个表: 车辆–车辆列表 carname | modelnumber | ... passedtest–包含汽车通过的所有测试: id | carname | testtype | date | ... 1 | carA | A | 2000 | 2 | carB | C | 2000 | 3 | carC | D | 2001 | 4 | carA | C | 2002 | 现在,如何从pass

假设我有两个表:

车辆
–车辆列表

carname | modelnumber | ...
passedtest
–包含汽车通过的所有测试:

id | carname | testtype | date | ...
1  | carA    | A        | 2000 |
2  | carB    | C        | 2000 |
3  | carC    | D        | 2001 |
4  | carA    | C        | 2002 |
现在,如何从
passedtest
表中选择一辆通过所有测试(a、B、C、D)的汽车

我在语句中尝试了
,但它也匹配通过一次测试的汽车。我正在寻找一个语句来匹配所有行中列表中的所有值。

这个怎么样

SELECT carname
FROM PassedTest
GROUP BY carname
HAVING COUNT(DISTINCT testtype) = 4
您还可以将其用作从
cars
表中获取信息的内部语句:

SELECT *
FROM cars
WHERE carname IN (
    SELECT carname
    FROM PassedTest
    GROUP BY carname
    HAVING COUNT(DISTINCT testtype) = 4
)

这种类型的问题称为
关系划分

SELECT  a.*
FROM    Cars a
        INNER JOIN
        (
            SELECT  CarName
            FROM    PassedTest 
            WHERE   testType IN ('A', 'B', 'C', 'D')
            GROUP   BY CarName
            HAVING  COUNT(*) = 4
        ) b ON a.CarName = b.CarName
如果对表
PassedTest
上的每个
CarName
未对
TestType
强制执行
UNIQUE
约束,则
COUNT()
上需要一个
DISTINCT
关键字,因此它将只对唯一值进行计数

SELECT  a.*
FROM    Cars a
        INNER JOIN
        (
            SELECT  CarName
            FROM    PassedTest 
            WHERE   testType IN ('A', 'B', 'C', 'D')
            GROUP   BY CarName
            HAVING  COUNT(DISTINCT TestType) = 4
        ) b ON a.CarName = b.CarName
但是,如果您只对
CARNAME
感兴趣,则不需要加入表。查询表
PassedTest
将满足您的需要

SELECT  CarName
FROM    PassedTest 
WHERE   testType IN ('A', 'B', 'C', 'D')
GROUP   BY CarName
HAVING  COUNT(*) = 4

您希望执行关系除法,这是一种SQL中未实现的操作。下面是一个示例,其中我们有一个产品供应商表和一个所需产品表:

CREATE TABLE product_supplier (
    product_id int NOT NULL,
    supplier_id int NOT NULL,
    UNIQUE (product_id, supplier_id)
);
INSERT INTO product_supplier (product_id, supplier_id) VALUES
(1, 1),
(2, 1),
(3, 1),
(1, 2),
(2, 2),
(3, 2),
(4, 2),
(2, 3),
(3, 3),
(4, 3);

CREATE TABLE reqd (
    product_id int NOT NULL,
    UNIQUE (product_id)
);
INSERT INTO reqd (product_id) VALUES
(1),
(2),
(3);
。。。我们希望找到所有提供所需产品的供应商,也许还有其他供应商。上述示例中的结果为供应商1和供应商2

最直接的解决方案是:

SELECT product_supplier.supplier_id
FROM product_supplier
LEFT JOIN reqd ON product_supplier.product_id = reqd.product_id
GROUP BY product_supplier.supplier_id
HAVING COUNT(reqd.product_id) = (SELECT COUNT(*) FROM reqd);
+-------------+
|供应商id|
+-------------+
|           1 |
|           2 |
+-------------+
如果我们想找到提供所有所需产品的所有供应商,而没有其他供应商(精确划分/无剩余),则在上述条件中再添加一个条件:

SELECT product_supplier.supplier_id
FROM product_supplier
LEFT JOIN reqd ON product_supplier.product_id = reqd.product_id
GROUP BY product_supplier.supplier_id
HAVING COUNT(reqd.product_id) = (SELECT COUNT(*) FROM reqd)
AND COUNT(product_supplier.product_id) = (SELECT COUNT(*) FROM reqd);
+-------------+
|供应商id|
+-------------+
|           1 |
+-------------+
另一种解决方案是重新表述问题:选择不存在所需产品的供应商,而供应商提供的产品中不存在所需产品。嗯:

SELECT DISTINCT supplier_id
FROM product_supplier AS ps1
WHERE NOT EXISTS (
    SELECT *
    FROM reqd
    WHERE NOT EXISTS (
        SELECT *
        FROM product_supplier AS ps2
        WHERE ps1.supplier_id = ps2.supplier_id AND ps2.product_id = reqd.product_id
    )
);
+-------------+
|供应商id|
+-------------+
|           1 |
|           2 |
+-------------+

谢谢,但我重复了我的输出,我想这是因为我使用了internal join来创建cars表。但是,这不适用于通配符,因为在这种情况下无法建立显式计数。但是我们正在硬编码4的值。。。如果我们添加一个测试呢?这应该是可以接受的答案,因为它不需要硬编码值