How to select records where two fields are unique - mysql

I have a table that looks something like this:
+-------------+----------+---------------+------------+
| Contract_ID | Name | Username | Password |
+-------------+----------+---------------+------------+
| 12345671 | Facebook | john.doe | password |
| 12345672 | Google | john.doe | password |
| 12345673 | Apple | martha.malone | doodlebear |
| 12345674 | Samsung | jimmy47 | parkour445 |
| 12345675 | HTC | rick.grimes | simpsons33 |
+-------------+----------+---------------+------------+
I'd like to select only records where there is a one to one ratio between username/password combination and contract id. In this case, that would mean I'd like to select the 3rd, 4th and 5th records in this table.
I've tried different combinations of the DISTINCT keyword but that doesn't seem to be the correct route to go. Is there a query that can return this information?
As a sort of bonus question: is there a query that can produce the opposite results (ie. only records where there is greater than 1 to 1 ratio between contract ids and username/password combination)?

You should use the GROUP BY clause together with the HAVING clause, for example:
SELECT Username, Password FROM Table
GROUP BY Username, Password
HAVING COUNT(*) = 1
The opposite is:
SELECT Username, Password FROM Table
GROUP BY Username, Password
HAVING COUNT(*) > 1

Group by (Name, Password) doesn't work?

Very naughty way of doing it,not good at all, but it works:
select distinct
least(col1, col2) as value1
, greatest(col1, col2) as value2
from yourtable

Related

MySQL - How to order duplicate rows in a key value pair table based on multiple columns?

So I have the following key/value pair table, where users submit data through a form and each question on the form is added to the table here as an individual row. Submission_id identifies each form submission.
+----+---------------+--------------+--------+
| id | submission_id | key | value |
+----+---------------+--------------+--------+
| 1 | 10 | manufacturer | Apple |
| 2 | 10 | model | 5s |
| 3 | 10 | firstname | Paul |
| 4 | 15 | manufacturer | Apple |
| 5 | 15 | model | 5s |
| 6 | 15 | firstname | Paul |
| 7 | 20 | manufacturer | Apple |
| 8 | 20 | model | 5s |
| 9 | 20 | firstname | Andrew |
+----+---------------+--------------+--------+
From the data above you can see that the submissions with id of 10 and 15 both have the same values (just different submission id). This is basically because a user has submitted the same form twice and so is a duplicate.
Im trying to find a way to order these table where the any duplicate submissions appear together in order. Given the above table I am trying to build a query that gives me the result as below:
+---------------+
| submission_id |
+---------------+
| 10 |
| 15 |
| 20 |
+---------------+
So I want to check to see if a submission where the manufacturer, model and firstname keys have the same value. If it does then these get the submission id and place them adjacently in the result. In the actual table there are other keys, but I only want to match duplicates based on these 3 keys (manufacturer, model, firstname).
I’ve been going back and forth to the drawing board quite some time now and have tried looking for some possible solutions but cannot get something reliable.
That's not a key value table. It's usually called an Entity-Attribute-Value table/relation/pattern.
Looking at the problem, it would be trivial if the table were laid out in conventional 1st + 2nd Normal form - you just do a join on the values, group by those and take a count....
SELECT manufacturer, model, firstname, COUNT(DISTINCT submission_id)
FROM atable
GROUP BY manufacturer, model, firstname
HAVING COUNT(DISTINCT submission_id)>1;
Or a join....
SELECT a.manufacturer, a.model, a.firstname
, a.submission_id, b.submission_id
FROM atable a
JOIN atable b
ON a.manufacturer=b.manufacturer
AND a.model=b.model
AND a.firstname=b.firstname
WHERE a.submission_id<b.submission_id
;
Or using sorting and comparing adjacent rows....
SELECT *
FROM
(
SELECT #prev.submission_id AS prev_submission_id
, #prev.manufacturer AS prev_manufacturer
, #prev.model AS prev_model
, #prev.firstname AS pref_firstname
, a.submission_id
, a.manufacturer
, a.model
, set #prev.submission_id:=a.submission_id as currsid
, set #prev.manufacturer:=a.manufacturer as currman
, set #prev.model:=a.model as currmodel
, set #prev.firstname=a.forstname as currname
FROM atable
ORDER BY manufacturer, model, firstname, submission_id
)
WHERE prev_manufacturer=manufacturer
AND prev_model=model
AND prev_firstname=firstname
AND prev_submission_id<>submission_id;
So the solution is to simply make your data look like a normal relation....
SELECT ilv.values
, COUNT(ilv.submission_id)
, GROUP_CONCAT(ilv.submission_id)
FROM
(SELECT a.submission_id
, GROUP_CONCAT(CONCAT(a.key, '=',a.value)) AS values
FROM atable a
GROUP BY a.submission_id
) ilv
GROUP BY ilv.values
HAVING COUNT(ilv.submission_id)>1;
Hopefully the join and sequence based solutions should now be obvious.

Relational MySQL Query

I have a table called users:
+----+---------+--------+----------------+----------------+----------+
| ID | Name | Zip | Email | Phone | Username |
+----+---------+--------+----------------+----------------+----------+
| 0 | Jill | 33333 | jill#aol.com | (123)123-1245 | idjill |
| 1 | Jack | 11111 | jack#aol.com | (123)111-1111 | idjack |
| 2 | Bob | 66666 | bob#aol.com | (123)222-2222 | idbob |
| 3 | jMarie | 12345 | jill#aol.com | (123)123-1245 | none |
+----+---------+--------+----------------+----------------+----------+
If I run SELECT * FROM users WHERE Phone=(123)123-1245 will return both ID# 0 and 3.
What I would like to do is be able to select the user and but also return any other users that have the same phone or email but not zip code. So for example if I run SELECT * FROM users WHERE Username= idjill I'd like it to return user 0 and 3 because they both have the same phone number.
How can I do that? Thanks. If anyone has a better idea for a title to this post, please share. My first post, sorry.
Edit: I think I need to clarify my question a bit. So I have this select query right here:
SELECT * FROM users WHERE Username = 'idjill' OR Email = 'idjill'
That perfectly returns ID 0, I would like it to return ID 0 and 3. Because the phone and the email match (I am using the same input to search between username and email).
How can I expand on this?
Using INNER JOIN like below.
SELECT DISTINCT a.* FROM users a INNER JOIN
(SELECT * FROM users WHERE Username='idjill') b
ON (a.Phone=b.Phone OR a.Email=b.Email) AND a.Zip<>b.Zip;
Nested query can be used
Select *
from users
where Phone = (select Phone from users where Username = "idjill");
You can use nested query like this.
SELECT *
FROM users
WHERE Phone=(SELECT PHONE
FROM users
WHERE Name='Jill') OR
Email=(SELECT Email
FROM users
WHERE Name='Jill');

Remove specific fields and show other fields in Mysql

I would like to ask for ways to solve this MySQL issue.
Currently, I have this select query
SELECT username, friend_username from friends
WHERE (username = "apple" or friend_username = "apple");
and it shows this Friends Table (below).
Friends Table
------------------------------
| username | friend_username |
------------------------------
| apple | orange |
| apple | pear |
| durian | apple |
------------------------------
But I would like to execute a select query to make it look like this (below).
------------
| username |
------------
| orange |
| pear |
| durian |
------------
Is there any possible ways to achieve this? Appreciate the help! Thank you.
I would write this as:
select case when username = 'apple' then friend_username else username end username
from friends
where 'apple' in (username, friend_username);
The where clause uses in to filter on rows where either username or friend_username is equal to 'apple'. Then, the case expression in the select clause displays the "other" column.

Getting a set with unique column values from MySQL

Say that I have a set with columns like this
user_id | username | updated_at | data...
user_id and username are not unique in the set, so you can have something like this
user_id | username | updated_at | data...
------------------------------------------
1 | test | 140****** | ...
4 | test2 | 140****** | ...
1 | test | 139****** | ...
7 | meh | 140****** | ...
But I would like to remove the duplicate occurrences; I tried GROUP BY but it gives me something unexpected as a lot of items are getting removed (I guess they appears later in the set as the query has a LIMIT in it).
If you need to select all the data - first of all u should decide how to get the updated_at and data columns.
In case you want to have the data concatenated and you want to have the latest updated_at you should do
SELECT user_id, username, max(updated_at), group_concat(data separator ',')
FROM table_name
GROUP BY user_id, username
ORDER BY user_id, username
LIMIT X
in that case your data will be ordered by user_id, and username
Note:
it is not clear from your question if you want to remove the data from the table itself or only from the result set.
Is this what you want?
select distinct user_id, username
from table t;

retrieving data from two mysql tables where the second table depends on the first

I have two MySql tables:
users(id_user, name, age, gender ).
ways(#id_user,id_way, start, end, date).
What I want is to retrieve all the ways with their corresponding users details.
So my result would be like this:
id_way | start | end | date | id_user | name | age | gender
---------------------------------------------------------------------------
2 | place1 | place2 | 12/06/2013 | 145 | john | 28 | m
Have you tried JOIN?
SELECT ways.id_way, ways.start, ways.end, ways.date, users.*
FROM ways JOIN users USING (id_user)