SQL query, find the user that does not have bank_account
I have two tables, the first one is table bank_customer, and the other is table user.
The table of bank_customer has many columns, including user_id and bank_account.
in table user, I have column id.
not every user has bank_account. so I want to query, users that do not have a bank_account, but it gets hard.
SELECT * FROM users, bank_customers
WHERE NOT users.id=bank_customers.user_id
so how can I query in SQL with this case?
and how to logic that case? for the next case I can find out by myself.
There are a few ways to go about that, but the simplest way would probably be using IN:
SELECT *
FROM users
WHERE id NOT IN (
SELECT user_id
FROM bank_customers
)
Related
I have a table of chat messages:
id, nToUserID, nFromUserID, strMessage
I'm trying find unique occurrences of messages between two users. NOT all the messages, just, is there at least one message to a user or from a user. I'll use this to show a list of "conversations" which could then be clicked to view the full chat thread.
I tried using a DISTINCT select, but that appeared to still give me multiple records between the same users.
I thought about a left JOIN, but again that appears to give me multiple or empty records.
If I understand correctly, you could use least() and greatest():
select distinct least(nToUserID, nFromUserID), greatest(nToUserID, nFromUserID)
from t;
If you want the other users, then use:
select distinct (case when nToUserID = ? then nFromUserID else nToUserID end) as userID
from t
where ? in (nToUserID, nFromUserID);
The ? is the id of the user you want the connections to.
You can use the count function to get the unique id pairs and their respective number of conversations.
SELECT nFromUserId, nToUserId, count(id) FROM `table` GROUP BY nFromUserId, nToUserId
Though this doesn't work if you need to count nFromUserId and nToUserId interchangeably.
I have two tables users and admin which contains same column emp_code.
I have a input field with button. I need to enter emp_code in input field.I need to get the rows from two tables which contains emp_code which i entered.
I need sql query to get the rows from two tables which contains emp_code which i entered.
I think you need all the users from user and admin table which have emp code similar to code given in the input field. Then you have to use "Union" in the sql query (Assuming both tables have the same columns):
SELECT username FROM ADMIN
WHERE EMP_CODE LIKE 'your_emp_code_here'
UNION
SELECT username FROM USERS
WHERE EMP_CODE LIKE 'your_emp_code_here'
It seems like you are new to DB Queries.
Well here is another simplest solution, (without join)
SELECT * FROM USERS, ADMIN
WHERE USERS.EMP_CODE = ADMIN.EMP_CODE
AND USERS.EMP_CODE like 'your_emp_code_here'
I've been reading through tutorials on Rails' active record model operations. And I'm a little confused on the difference between .select and .group. If I wanted to get all the names of all my users in table User I believe I could do:
myUsers = User.select(:name)
so how would that be different from saying:
myUsers = User.group(:name)
thanks,
Will
The two differ like this:
User.select(:name)
is equivalent to this SQL statement
SELECT name from users;
and
User.group(:name)
is equivalent to
SELECT * from users GROUP BY name;
The difference is that with select(:name) you are taking all rows ordered by id, but only with column name. With group(:name) you are taking all rows and all columns, but ordered by column name.
User.pluck(:name) will be the fastest way to pull all the names from your db.
There is #to_sql method to check what DB query it is building. By looking at the DB query, you can confirm yourself what is going on. Look the below example :-
arup#linux-wzza:~/Rails/tv_sms_voting> rails c
Loading development environment (Rails 4.1.4)
>> Vote.group(:choice).to_sql
=> "SELECT \"votes\".* FROM \"votes\" GROUP BY choice"
>> Vote.select(:choice).to_sql
=> "SELECT \"votes\".\"choice\" FROM \"votes\""
>>
Now it is clear that Vote.select(:choice) is actually, SELECT "votes"."choice" FROM "votes", which means, select choice column from all rows of the table votes.
Vote.group(:choice) is grouping the rows of the votes table, based on the column choice and selecting all columns.
If I wanted to get all the names of all my users in table User.
Better is User.pluck(:name).
I have two tables: all_users and vip_users
all_users table has a list of all users (you don't say?) in my system and it currently has around 57k records, while vip_users table has around 37k records.
Primary key in both tables is an autoincrement id field. all_users table is big in terms of attribute count (around 20, one of them is email), while vip_users table has only (along with id) email attribute.
I wanted to query out the "nonVip" users by doing this (with help of this question here on SO):
SELECT all_users.id, all_users.email
FROM all_users
LEFT OUTER JOIN vip_users
ON (all_users.email=vip_users.email)
WHERE vip_users.email IS NULL
And now, finally coming to the problem - I ran this query in phpmyadmin and even after 20 minutes I was forced to close it and restart httpd service as it was taking too long to complete, my server load jumped over 2 and the site (which also queries the database) became useless as it was just loading too slow. So, my question is - how do I make this query? Do I make some script and run it over night - not using phpmyadmin (is this maybe where the problem lies?), or do I need to use different SQL query?
Please help with your thoughts on this.
Try indexing the fields email on both tables, that should speed up the query
CREATE INDEX useremail ON all_users(email)
CREATE INDEX vipemail ON vip_users(email)
As written, you're not getting the results you're looking for. You're looking for vip_users rows where the email matches an email in users, and is also NULL.
Is there a reason you want vip_users to have a separate id from users? If you change the vip_users id field to a fk on the users id field, yo would then change your select to:
SELECT all_users.id, all_users.email
FROM all_users
LEFT OUTER JOIN vip_users
ON (all_users.id=vip_users.id)
WHERE vip_users.email IS NULL;
There's no reason this query should take any discernible about of time. 37k records is not a very big table....
I think NOT IN is faster and used less resource than LEFT OUTER JOIN.
Can you try -
SELECT *
FROM all_users
WHERE id NOT IN (SELECT id
FROM vip_users
WHERE email IS NULL);
Please forgive my ignorance here. SQL is decidedly one of the biggest "gaps" in my education that I'm working on correcting, come October. Here's the scenario:
I have two tables in a DB that I need to access certain data from. One is users, and the other is conversation_log. The basic structure is outlined below:
users:
id (INT)
name (TXT)
conversation_log
userid (INT) // same value as id in users - actually the only field in this table I want to check
input (TXT)
response (TXT)
(note that I'm only listing the structure for the fields that are {or could be} relevant to the current challenge)
What I want to do is return a list of names from the users table that have at least one record in the conversation_log table. Currently, I'm doing this with two separate SQL statements, with the one that checks for records in conversation_log being called hundreds, if not thousands of times, once for each userid, just to see if records exist for that id.
Currently, the two SQL statements are as follows:
select id from users where 1; (gets the list of userid values for the next query)
select id from conversation_log where userid = $userId limit 1; (checks for existing records)
Right now I have 4,000+ users listed in the users table. I'm sure that you can imagine just how long this method takes. I know there's an easier, more efficient way to do this, but being self-taught, this is something that I have yet to learn. Any help would be greatly appreciated.
You have to do what is called a 'Join'. This, um, joins the rows of two tables together based on values they have in common.
See if this makes sense to you:
SELECT DISTINCT users.name
FROM users JOIN conversation_log ON users.id = converation_log.userid
Now JOIN by itself is an "inner join", which means that it will only return rows that both tables have in common. In other words, if a specific conversation_log.userid doesn't exist, it won't return any part of the row, user or conversation log, for that userid.
Also, +1 for having a clearly worded question : )
EDIT: I added a "DISTINCT", which means to filter out all of the duplicates. If a user appeared in more than one conversation_log row, and you didn't have DISTINCT, you would get the user's name more than once. This is because JOIN does a cartesian product, or does every possible combination of rows from each table that match your JOIN ON criteria.
Something like this:
SELECT *
FROM users
WHERE EXISTS (
SELECT *
FROM conversation_log
WHERE users.id = conversation_log.userid
)
In plain English: select every row from users, such that there is at least one row from conversation_log with the matching userid.
What you need to read is JOIN syntax.
SELECT count(*), users.name
FROM users left join conversion_log on users.id = conversation_log.userid
Group by users.name
You could add at the end if you wanted
HAVING count(*) > 0