简体   繁体   中英

ALL operator clause in SQL query

I have this table schema.

Machine​(machine_id​, size)
Operator​(operator_id​, name)
OperationLog​(machine_id, operator_id, date, comment)
  ​machine_id: FK(Machine)
  operator_id: FK(Operator)

Assuming I want a query that only gives me the name of the operators that operated all machines with size above 5m2

Would using the ALL operator give me the desired result? As in, from the list of Machines with size above 5, Operators that have Logs must match all of those machines.

SELECT O.name
  FROM Operator O NATURAL JOIN OperationLog L
  WHERE L.machine_id​ = ALL (
      SELECT M.machine_id​     
      FROM Machine M  
      WHERE size >5);

Or would I need to do a "double negation" like so?

SELECT O.name
FROM Operator O
WHERE NOT EXISTS(
   SELECT M.machine_id​
   FROM Machine M 
   EXCEPT
   SELECT L.machine_id​            
   FROM OperationLog L NATURAL JOIN Machine M      
   WHERE L.operator_id = O.operator_id
         AND size >5);

I feel I am complicating too much and there's probably a better way.

Count how many different machines of (size >= 5) each operator used and compare that number to the total number of such machines:

SELECT op.name
FROM operator op
    INNER JOIN operationlog l
        ON op.operator_id = l.operator_id
    INNER JOIN machine m
        ON l.machine_id
WHERE m.size >= 5
GROUP BY op.name
HAVING COUNT(DISTINCT m.machine_id) = (
        SELECT COUNT(*)
        FROM machine
        WHERE size >= 5
)

I am a fan of using group by and having for this purpose:

SELECT O.name
FROM Operator O JOIN
     OperationLog L
     ON L.operator_id = O.operator_id JOIN
     Machine M 
     ON L.machine_id​ = M.machine_id​ 
WHERE M.size > 5
GROUP BY O.name  
HAVING COUNT(DISTINCT M.machine_id) = (SELECT COUNT(DISTINCT M2.machine_id)
                                       FROM Machine M2  
                                       WHERE size > 5
                                      );

If there are not duplicates in the tables, then use COUNT(*) rather than COUNT(DISTINCT) .

I should note that I strongly discourage you from using NATURAL JOIN . It is a bug waiting to happen. Why? It simply uses columns that have the same names. It doesn't even use the same types. For instance, most tables I create have columns for CreatedBy and CreatedAt and it would use these columns.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM