combining 2 tables in mysql - mysql

Here is what I am looking to do but I have my doubts if its possible or not!
I have 2 tables, one is called users and the other is answers. I need to combine the results into a single statement, and order the table by time. the tricky part is that I have time on both tables and I need to take both time fields into account for ordering the results.
This is my unsuccessful attempt to come up with the query:
SELECT * FROM ( SELECT id, username, first_name, last_name, time FROM users
UNION ALL
SELECT id, answer, pid, uid, time FROM answers ) as AB
ORDER BY `AB.time`
UPDATE
I have come up with the following SQL Query:
SELECT username AS user, '' as page , '' as content , time FROM users
UNION ALL
SELECT (SELECT username FROM users WHERE `id`=`uid`) AS user, pid AS page, answer AS content, time FROM answers
ORDER BY `time` DESC
its what I am looking for but for some reason the user field in the second SELECT query is showing as null! any idea why?

SELECT id, username, first_name, last_name, time FROM users
UNION ALL
SELECT id, answer, pid, uid, time FROM answers
ORDER BY 'time`
solution to have different column name for each table
SELECT id AS t1_id,
username AS t1_username,
first_name AS t1_first_name,
last_name AS t1_last_name,
NULL ast2_id,
NULL AS t2_answer,
NULL AS t2_pid,
NULL AS t2_uid,
time
FROM users
UNION ALL
SELECT NULL AS t1_id,
NULL AS t1_username,
NULL AS t1_first_name,
NULL AS t1_last_name,
id ast2_id,
answer AS t2_answer,
pid AS t2_pid,
uid AS t2_uid,
time
FROM answers
ORDER BY time

If users.id and answers.uid are supposed to be the same then this should work:
SELECT u.*, a.* FROM users AS u
JOIN answers AS a ON a.uid = u.id
ORDER BY a.time

Related

more efficient way to select duplicate users

Im trying to select * from all duplicate rows in users, where a duplicate is defined as two users sharing the same first_name and last_name. (I need to process the other columns that might differ)
Im using MySQL 8.0.28.
My first try was to literally translate my requirement:
select * from `users` AS u1 where exists (select 1 from `users` AS u2 WHERE `u2`.`first_name` = `u1`.`first_name` AND `u2`.`last_name` = `u1`.`last_name` AND `u2`.`id` != `u1`.`id`)
Which, obviously, has a horrendous execution time.
My current query is
SELECT * from users where Concat(first_name," ",last_name) IN (select Concat(first_name," ",last_name) from `users` GROUP BY first_name, last_name HAVING COUNT(*)>1)
which is vastly more efficient, but still takes more than 100ms for 8000 records. I suppose a solution that doesn't use concat could benefit from indicies and would not need to calculate the result for each row.
Also, I couldn't get group by to work because I need so select all columns of all rows that are duplicates, not just the distinct first_name's and last_name's. Also because I don't want to disable ONLY_FULL_GROUP_BY (not sure if disabling that would help anyway).
Is there a more efficient, proper way to select these duplicate rows?
I would just use an aggregation approach here:
SELECT *
FROM users
WHERE (first_name, last_name) IN (
SELECT first_name, last_name
FROM users
GROUP BY 1, 2
HAVING COUNT(*) > 1
);
On MySQL 8+, we can also use COUNT() as an analytic function here:
WITH cte AS (
SELECT *, COUNT(*) OVER (PARTITION BY first_name, last_name) AS cnt
FROM users
)
SELECT *
FROM cte
WHERE cnt > 1;

What Am I Missing? MySQL Left Join Most Newest Entry From 2nd Table

I need a fresh pair of eyes on this. I have two tables, one of which has users and the second which contains login records, multiple records for each user. What I'm trying to do is select all entries from the first table, and the most recent record from the second table, e.g., a list of all users but only show the most recent activity. Both tables have auto increment in the ID column.
My code currently is thus:
SELECT u.user_id, u.name, u.email, r.rid, r.user_id
FROM users AS u
LEFT JOIN login_records AS r ON r.user_id = u.user_id
WHERE
r.rid = (
SELECT MAX( rid )
FROM login_records
WHERE user_id = u.user_id
)
I've scoured answers to similar questions on SO and tried all of them, but results have been either returning nothing or only getting odd results (not necessarily the newest one). ID in both tables is auto-increment, so I thought it should be a relatively simple matter to get the only or highest ID for a particular user, but it either returns nothing or a completely different selection each time.
It's my first time using JOIN - do I have the wrong JOIN? Do I need to ORDER or GROUP things differently?
Thanks for your help. It's got to be something simple, since Danny Coulombe's answer appearing here seems to work for other users.
You will need a subquery I believe:
https://www.db-fiddle.com/f/2wudMDVxReYJz4FEyG19Va/0
CREATE TABLE users (
user_id INT UNSIGNED NOT NULL
AUTO_INCREMENT PRIMARY KEY
);
CREATE TABLE users_logins (
user_login_id INT UNSIGNED NOT NULL
AUTO_INCREMENT PRIMARY KEY,
user_id INT UNSIGNED NOT NULL
);
INSERT INTO users SELECT 1;
INSERT INTO users SELECT 2;
INSERT INTO users_logins SELECT 1,1;
INSERT INTO users_logins SELECT 2,1;
INSERT INTO users_logins SELECT 3,1;
INSERT INTO users_logins SELECT 4,1;
INSERT INTO users_logins SELECT 5,2;
INSERT INTO users_logins SELECT 6,2;
And the query:
SELECT
u.user_id, ul.latest_login_id
FROM users u
LEFT JOIN
(
SELECT user_id, MAX(user_login_id) latest_login_id
FROM users_logins
GROUP BY user_id
) ul ON u.user_id = ul.user_id
You have to ORDER BY with what column you want to display by desc, for example ORDER BY last_login DESC.
Change the last_login column with the column you want to order, but you must first declare the last_login column after SELECT.
How about replacing all rid in where clause and corrolated subquery by record_id?
SELECT u.user_id, u.name, u.email, r.rid, r.record_id, r.user_id
FROM test_users AS u
LEFT JOIN test_login_records AS r ON r.user_id = u.user_id
WHERE
(r.record_id = (
SELECT MAX(record_id)
FROM test_login_records
WHERE user_id = u.user_id
) OR r.record_id is null);
Test here

MySQL look for duplicates on multiple fields

I have a MySQL database with the following fields:
id, email, first_name, last_name
I want to run an SQL query that will display rows where id and email exists more than once.
Basically, the id and email field should only have one row and I would like to run a query to see if there are any possible duplicates
If you just want to return the id and email that are duplicated, you can just use a GROUP BY query:
SELECT id, email
FROM yourtable
GROUP BY id, email
HAVING COUNT(*)>1
if you also want to return the full rows, then you have to join the previous query back:
SELECT yourtable.*
FROM
yourtable INNER JOIN (
SELECT id, email
FROM yourtable
GROUP BY id, email
HAVING COUNT(*)>1
) s
ON yourtable.id = s.id AND yourtable.email=s.email
You'll want something like this:
select field1,field2,field3, count(*)
from table_name
group by field1,field2,field3
having count(*) > 1
See also this question.
You can search for all ids that meet a specific count by grouping them and using a having clause like this:
SELECT id, COUNT(*) AS totalCount
FROM myTable
GROUP BY id
HAVING COUNT(*) > 1;
Anything this query returns has a duplicate. To check for duplicate emails, you can just change the column you're selecting.

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

Help with a MySql Query - The Rows Holding the Group-wise Maximum of a Certain Column

I need help returning a relevant result for this query. I have one table that I am hitting with three columns. trans_date, trans_amount and user_id
what I am trying to determine is this. For a given user_id when was the last trans_date and what was the trans_amount.
I'm having trouble returning the correct transaction_amount. Here is my code so far. It's returning the correct date but the amount is not right
select user_id, trans_date, trans_credit
from table
WHERE trans_credit =
(select max(trans_date) from inclick_account_act as f
where f.user_id = table.user_id);
Thanks in advance
If I understand you correctly you just want to get the most recent transaction for all users.
SELECT user_id, trans_date, trans_credit
FROM `table`
GROUP BY user_id
ORDER BY trans_date DESC;
How about something like
SELECT t.*
FROM table t INNER JOIN
(
SELECT user_id,
MAX(trans_date) max_trans_date
FROM table
GROUP BY user_id
) MaxDates ON t.user_id = MaxDates.max_trans_date