Fuginator
Fuginator

Reputation: 229

Nested select statements in mySQL

I have an existing SQL query that works fine in SQL Server, that I would like to make work in MySQL. I have cleaned it up a bit, and fiddled with the back-ticks for column / table names, etc. but cannot get it to work.

Here is the statement in question:

SELECT `EmployeeID`
FROM `Employee`
WHERE
(
   (
      SELECT COUNT(*) AS A
      FROM `TimeClock`
      WHERE (`EmployeeID` = `Employee.EmployeeID`)
         AND (`InOut` = 'True')
   ) > (
      SELECT COUNT(*) AS B
      FROM `TimeClock` AS `TimeClock_1`
      WHERE (`EmployeeID` = `Employee.EmployeeID`)
         AND (`InOut` = 'False')
   )
)

This should return any EmployeeID's that have more InOut = True than InOut = False in the TimeClock table.

Thanks.

Upvotes: 2

Views: 771

Answers (1)

Adam Wenger
Adam Wenger

Reputation: 17540

This should provide you with the EmployeeId values where there are more values of InOut True than False

SELECT e.EmployeeId
FROM Employee AS e
INNER JOIN
(
   SELECT tc.EmployeeID
      , SUM(CASE
               WHEN tc.InOut = 1 THEN 1 ELSE 0
            END) AS InOutTrue
      , SUM(CASE
               WHEN tc.InOut = 0 THEN 1 ELSE 0
            END) AS InOutFalse
   FROM TimeClock AS tc
   GROUP BY tc.EmployeeId
) AS t ON e.EmployeeId = t.EmployeeId
WHERE t.InOutTrue > t.InOutFalse

The two alternatives I came up with show similar performance on my VERY SMALL unindexed test data. I would recommend you test them against your own data to see if they make any difference:

This one is pretty much the same, but using total record count instead of InOutFalse.

SELECT e.EmployeeId
FROM Employee AS e
INNER JOIN
(
   SELECT tc.EmployeeID
      , COUNT(1) AS RecordCount
      , SUM(CASE
               WHEN tc.InOut = 1 THEN 1 ELSE 0
            END) AS InOutTrue
   FROM TimeClock AS tc
   GROUP BY tc.EmployeeId
) AS t ON e.EmployeeId = t.EmployeeId
WHERE t.InOutTrue > RecordCount - t.InOutTrue

I am not sure if MySQL will require the CAST I used here, but SQL Server did. (That is what I tested these with) It could not perform a SUM on a BIT column.

SELECT e.EmployeeId
FROM Employee AS e
INNER JOIN TimeClock AS tc ON e.EmployeeId = tc.EmployeeId
GROUP BY e.EmployeeId
HAVING SUM(CAST(tc.InOut AS INT)) > (COUNT(1) - SUM(CAST(tc.InOut AS INT)))

If all three perform similarly, it then comes down to personal preference.

Upvotes: 1

Related Questions