How Would I Nest This MySQL Select Query? - php

I have a table with user payment details, and another table with a list of users. I want to get the balance of all users from the payment details, but only for users that are not banned (which is a column in the users table).
I am somewhat new to nested queries so I am not sure how to do this?
Here is what I have tried so far...
mysql_query("
SELECT SUM(balance)
FROM payment_details
WHERE (SELECT ban
FROM users
WHERE username=username
) != '1'
")
Note: Username is a column in both tables.
The above query does not work.
To Recap: There are two tables: payment_details and users. I want to add together the balance column for all the users that are not banned.

Don't use a subquery here. Instead, use a JOIN.
SELECT SUM(payment_details.balance) FROM payment_details
JOIN users ON payment_details.username = users.username
WHERE ban != '1'

Agreed, a join is probably what you want.
However to answer the specific question, you could try a query like:
SELECT SUM(payment_details.balance)
FROM payment_details
WHERE payment_details.username in (
SELECT users.username
FROM users WHERE ban != '1'
);
Note that it wasn't clear from the question whether you wanted the sum for each individual user, or the total sum for all users. The above query provides the latter -- not grouped by user.

the query is:
SELECT SUM(balance) FROM payment_details JOIN users ON payment_details.username=users.username WHERE users.ban !='1' group by payment_details.username
by the way, working on the users ids would be much better than on the usernames

Related

Updating a row based on number of existing records

I'm trying to update a number of rows in a user table based on a value occurring more than once. In this case it's user email - as the user can sign up to multiple websites hosted in this application.
UPDATE users SET email = REPLACE(email,'#', CONCAT('+',user_id,'#'))
WHERE user_id IN (
SELECT user_id FROM users HAVING COUNT('email') > 1
);
This query gives me the following error;
ERROR 1093 (HY000): You can't specify target table 'customer_entity' for update in FROM clause
I've tried a number of variations but none of these seem to work.
MySQL does not support this syntax. Instead, you can self-join an aggregate query:
UPDATE users u
INNER JOIN (SELECT user_id FROM users GROUP BY user_id HAVING count(email) > 1) u1
ON u1.user_id = u.user_id
SET u.email = REPLACE(e.email,'#', CONCAT('+', u.user_id, '#'))
The two links I cited have lots of great suggestions, and GMB's suggestion sounds promising, too.
Q: Have you really looked at each of these (multiple different!) alternatives, and tried them out yourself, with your dataset? What happened?
SUGGESTION (taking GMB's example):
Verify the select works (returns one or more rows):
SELECT user_id FROM users GROUP BY user_id HAVING count(email) > 1)
Combine the "update" with the "join" (different syntax):
UPDATE users u1
SET u1.email = REPLACE(e.email,'#', CONCAT('+', u1.user_id, '#'))
INNER JOIN users u2
ON u1.user_id = u2.user_id
GROUP BY u2.user_id HAVING count(u2.email) > 1;
Please let us know the results.

Join database and count

I'm trying to list informations about a table and one of that information is how much cars an user has. I have two databases, one is users and the other is cars. The table cars has a column that is owner that holds the id of the owner. What I want to know is: How to list all users and along with that the total of cars that each user has?
$users = Users::all();
This code returns an array with all users, what I want is to pass the total of cars that each user has on the same $users variable. How can I do that? Is there a way to join the other table, count and then return or something like that?
#edit
I tried like this, but doesn't work:
$users = Users::join('cars', 'cars.owner', '=', 'users.id')->select(DB::raw('count(cars.car_id) as total'))->get();
You need the group by statemant:
select users.name, count(*) as counter from users
join cars on ... group by users.name;
Okay here in more Detail:
You have to join the users table with the cars table. You do that, yes.
Then you have to select one col from the user table and one count(*) as counter
The trick is now, to "group by" the col from the users table. That matches all double user rows to one row and count how much cars one user has
The select statement is:
"select users.id, count(*) as counter from Users join Cars on cars.owner=users.id group by users.id"
Thats all ... hope that help you
I think this will help you...
Users::with([
'cars' => function($q){
$q->select([DB::raw("count(car_id) as total"), "car_id"])
->groupBy('car_id');
}
])->get();
You can try this SQL query in raw. I tried and it works.
SELECT users.name as User_Name, COUNT(cars.user_id) as Car_Count
FROM users
LEFT JOIN cars
ON users.id=cars.user_id
GROUP BY users.id

Php mysql Query two usernames in one row based on id from another table

I am somewhat new to coding and have been trying to write what I thought would be a straightforward sql query. Please help :)
Table 1: Users
id = user idt
username = user name
Table 2: Orders
orderid = order id
order_to = user id of person buying
order_from = user id of person selling
oder_details = text
Basically I want to:
"Select Username(from), Username(to), order_details FROM mytables WHERE Order id = 1;"
And get the result as 1 row, I'm not sure how to proceed. I thought I could do this with concatenation or something... Can anyone help?
You need to use JOIN to link the tables together.
SELECT fu.username AS fromUser, tu.username AS toUser, o.order_details
FROM Orders o
INNER JOIN Users fu
ON fu.id = o.order_to
INNER JOIN Users tu
ON tu.id = o.order_from
WHERE o.orderid = '1';
Because you have two different users that you need the username from, you need to JOIN the Users table twice to get both user's usernames. Each table needs to have it's own alias fu and tu to allow MySQL to differentiate between them. The same goes for the column names in your SELECT statement so that when you fetch the results with PHP, php can differentiate between the two usernames.
You are looking for a JOIN. This can be done with a keyword or through WHERE clauses. For example,
SELECT * FROM Orders JOIN Users ON Orders.order_to=Users.id
The documentation can be found here: http://dev.mysql.com/doc/refman/5.0/en/join.html.
I'll leave it as an exercise to figure out how to JOIN the order_from.

Optimise & improve performance of this MYSQL query

SELECT u.id, u.honour, COUNT(*) + 1 AS rank
FROM user_info u
INNER JOIN user_info u2
ON u.honour < u2.honour
WHERE u.id = '$id'
AND u2.status = 'Alive'
AND u2.rank != '14'
This query is currently utterly slowing down my server. It works out based on your honour what rank you are within the 'user_info' table which stores it out of all our users.
Screenshot for explain.
http://cl.ly/370z0v2Y3v2X1t1r1k2A
SELECT u.id, u.honour, COUNT(*)+1 as rank
FROM user_info u
USE INDEX (prestigeOptimiser)
INNER JOIN user_info u2
ON u.honour < u2.honour
WHERE u.id='3'
AND u2.status='Alive'
AND u2.rank!='14'
I think the load comes from your join condition '<'.
You could try to split your query or (or if you prefer a subquery) and use the honour index for the count.
SELECT id, honour INTO #uid, #uhonour
FROM user_info
WHERE id = '$id';
SELECT #uid, #uhonour, COUNT(honour) + 1 as rank
FROM user_info
WHERE status = 'Alive'
AND rank != '14'
AND #uhonour < honour;
Firstly, you should add a group by clause so that your query makes sense.
Secondly, you should change the status column to hold an integer to make the index smaller.
Thirdly, you should create an index on id and status like this:
alter table user_info add index idxID_Status (id, status)
Finally, to obtain ranks you should take a look at this answer. Additionally you should add a way to order them... getting a rank without order is not really a rank.
As we can see from explain, MySQL uses the wrong index here. To start with, just drop all indexes and create a new one, containing at least these two fields: Id and Honour. It should boost up performance considerably.
ALTER TABLE user_info ADD INDEX myIndex (id, honour);

Basic MySQL question: how to get rows from one table that are not in another table?

I have a list of usernames (with a column called "username") + other info in my "users" table.
I also have another list of usernames (with a column called "username") in my smaller "recentusers" table.
How can I create a mysql query to get all the usernames that are in the "users" table but not in the "recentusers" table?
I know it is probably very simple, but any help would be appreciated!
select username from users where username not in (select username from recentusers)
Then after the first username add in the other information you want to select as well.
As pointed out by OMG Ponies, this query will run as fast as using Left Join or Is null.
The NOT IN keyword should be helpful :
SELECT username
FROM users
WHERE username NOT IN (
SELECT username
FROM recentusers
)
SELECT * FROM users
LEFT JOIN recentusers USING (username)
WHERE recentusers.username IS NULL;
You can also use a left join (which will perform faster than a subquery):
SELECT
users.username
FROM
users LEFT JOIN recentusers
ON users.username = recentusers.username
WHERE
recenterusers.username is null
Joins should be faster than subqueries, though I do not really know if mysql supports this.
select * from users
left outer join recentusers
on users.key = recentusers.key

Categories