Query design, temporary table? MySQL - mysql

I have two tables, users and events, and I want to select e.g. 6 users from the USERS table and list all of their events in chronological order of the event date
table design:
USERS EVENTS
user_id >>>> user_id
event_title
event_date
Do I select all the events into a temporary table then query that with "order by" or is there a more efficient way to do this within the query itself?

This will select six arbitrary users from your users table and fetch all their events:
SELECT user_id, event_title, event_date
FROM EVENTS
WHERE user_id IN
(
SELECT user_id
FROM USERS
LIMIT 6
)
ORDER BY event_date
You should change the subselect to select six specific users based on your desired criteria, instead of just the first six that MySQL finds.
You should add indexes to ensure that this runs efficiently. Use EXPLAIN SELECT ... to check which indexes are being used.

Related

Query to find users with one row in table

I have a table "users" which has multiple columns in which column "status" has multiple values like 1,0,3,2,4. There is column "user_id" which doesn't contain unique values since, this is foreign key of another table called "user_master".
so here in "users" table we have multiple values of the one user.
So, Here is my actual query is that i would like to write a sql query to find users has only one entry in table "users" with particular status value.
For e.g. I would like to fetch all such users with status=2 and their entry in table is not more than 1. Like if user has multiple entries with status 2,1,4 in table which should not be return in query.
It should yield those users which has only one entry in table and which is of status = 2
That must be what you use:
Select count(u.user_id) AS cnt, u.*
from user u
where u.status = 2
group by u.user_id, u.status
having cnt = 1;
WITH tmp AS(
SELECT Stud_Id,COUNT(*) AS 'Count' FROM Student_tbl GROUP BY Stud_Id
)
SELECT * FROM tmp WHERE Count = 1 AND Status = 2
You have to add field in GROUP BY Clause whichever you want to use in SELECT clause.
I have researched it and found answer for it.
And query goes like this.
select count(id) as cnt,
user_id,status from users
group by user_id
having cnt < 2 and status=2
First it will group the things having count less than 2 and then which will check for status.

MySQL view count and sum and other operations from multiple tables

Here is my situation:
I have 4 tables that all contains a column called score in all of these tables my goal for a view to create operations to the result of the 4 tables getting the following values:
Total score
Total number of rows
average (total score / number of rows)
Now i know that i would be able to create the view as:
(SELECT * FROM table1 where condition) + (SELECT * FROM table2 where condition)
So on and so forth.
but for each of the three goals i have i would have to nested select all tables atleast 2 times.
So my question is how do you handle a case like this? is there any operation in sql that makes this an easy task or am i bound to do something redundant?
Update
So my full case is that every use in my system has something called a division_id now i want to use this ID to find out what the score is for each division:
(PLEASE IGNORE THE _COPY)
You could use a UNION to join the 4 tables, since there is no join condition. There are a couple of ways that you could do this with the division field. Probably the most concise is:
select division_id, count(*), avg(scores.score), sum(scores.score) from
user join
(select id as user_id, score from user
UNION ALL
select user_id, score from test_score
UNION ALL
select user_id, score from task_score
UNION ALL
select user_id, score from offline_score) as scores
on user.id = scores.user_id
group by division_id
Link to SQLFiddle

sql conditional when users id does not show up in another table

I have two tables, both contains a created_at column.
users: id, first_name, last_name, created_at
entries: id, user_id, created_at
Below is the query that returns all entries and the users, but I need to add a conditional to display the appropriate created_at date
select users.id, first_name, last_name, entries.created_at
from users left join sweepstakes_entries on users.id = entries.user_id;
I imported a csv of mail-in entries into the users table and I need to write a sql statement that returns all entries with the user that entered them, as well as the mail entries I entered into the users table.
I used a left join to return the users that were imported from the csv file, since they don't have any entries in the entries table, but I still need to return them in the sql results.
With that said, I need to display the created_at date for when the entry was created from the entries table (entries.created_at), but I need to do a conditional on the created_at so when it pulls in the users (users who were imported from the mail-in csv) it will not have a created_at date from the entries table to tie it to, so I need to do a conditional that instead of using entries.created_at, I use users.created_at.
In theory:
if(this record's users.id does not show up in the entries table)
use users.created_at as created_at
else
use entries.created_at as created_at
You have multiple options:
Use COALESCE - Returns first non null value from a list. SELECT COALESCE(Col1, Col2, Col3)
Use CASE WHEN, THEN to check if Col1 is null or = "0000-00-00" return Col2 or vice versa
By the sounds of it you could simply use COALESCE
select users.id,
first_name,
last_name,
COALESCE(entries.created_at, users.created_at) AS created_at
from users
left join sweepstakes_entries on users.id = entries.user_id;
You could also use the less portable IFNULL:
IFNULL(entries.created_at, users.created_at) AS created_at

MySQL get most recent entries from a big table

I have a table with more than 50k entries and a few users:
transactions Table:
ID
USER
VALUE
TIMESTAMP
users Table:
USER
TYPE
REGION
I would like to get the most recent transactions for each user. So far I am using the following GROUP BY statement, but it is slow (takes 5-10sec approx):
select ID , max(TIMESTAMP) as TIMESTAMP from transactions group by USER;
Is there a faster statement to retrieve the most recent entries?
First of all as per my understanding ID columns should keep unique values in transaction table so group by should be on USER field as per your requirement.
Further you can try below query. I am not sure but you can compare its time with your query and use accordingly.
SELECT
USER , TIMESTAMP
FROM
(SELECT USER,TIMESTAMP FROM transactions ORDER BY ID DESC) a
GROUP BY USER;
Assuming there will be an index on USER column as this is common between both tables.
Try this,
select u.*,tr.* from users as u
outer apply
(
select top 1 * from transactions as t
where t.USER= u.USER
order by t.ID desc
)as tr

Select the max value from two tables

I have a query like this, to select the most recent time someone was contacted:
SELECT `user_id`, `last_contact`
FROM `emails_sent`
group by `user_id`
order by `last_contact` desc
The above code gives a table with the last contact time for each user. Now, I have another table with contacts to users, a table with columns user_id and last_contact, among others.
How can I make my select use both tables and select the last contact time for each user from the two tables?
Summarize the union of two summary queries, something like this.
SELECT user_id,
MAX(user_date) user_date
FROM
(
SELECT user_id,
MAX(last_contact) user_date
FROM emails_sent
GROUP BY user_id
UNION ALL
SELECT whatever_user_id_column user_id,
MAX(whatever_date_column) user_date
FROM whatever_table
GROUP BY user_id
)a
GROUP BY user_id