Search code examples
mysqlsqlentity-attribute-value

Get "users without specific row "


I have a table that holds information about registered users. Something similar to this:

umeta_id | user_id | meta_key    | meta_value
---------|---------|-------------|-------------
 1       | 1       | nickname    | value
 2       | 1       | first_name  | value
 3       | 1       | custom_key  | value
 4       | 2       | nickname    | value
 5       | 2       | first_name  | value
 6       | 3       | nickname    | value
 7       | 3       | first_name  | value
 8       | 3       | custom_key  | value

There are two forms to register, so the row count that corresponds to a registered user varies depending on which form is used when registering.

For example, if a user used form A to register, there's a row with custom_key that's associated with that user. If the user used form B, there's no custom_key row. Compare the rows with user_id 1 and 2. 1 registered using form A, and 2 registered using form B.

I can get the users with custom_key (that used form A), but how do I get the users that used form B, that is, users without custom_key row?

This SELECT * FROM rfs_usermeta WHERE meta_key = 'custom_key' returns rows/users that used form A. I need to do the opposite.

In JS, I'd write it as:

var users = {};

// loop usermeta rows
for (var row in rfs_usermeta) {
    // group rows with same user_id
    users[row.user_id][row.meta_key] = value;
}

var result = [];

// loop grouped rows
for (var user in users) {
    // assume users don't have custom_key row
    var rowExists = false;
    // loop user keys
    for (var key in user) {
        // check if custom_key exists 
        if (key == "custom_key") {
            // mark current user
            rowExists = true;
            break;
        }
    }
    // ignore marked users
    if (!rowExists) {
        result.push(user);
    }
}

Solution

  • SELECT * 
    FROM  rfs_usermeta 
    WHERE user_id NOT IN( SELECT user_id FROM rfs_usermeta WHERE meta_key='custom_key')
    

    You never want to filter with PHP if you can filter with your database. Your database is designed to gather/order/filter data and can do this super fast, where a PHP loop is a lot slower.