I'm trying to figure out how to find first occurrence of distinct Emails based on user column ordered by time, so assume my table is like this
| User | Email | | Time| |ID|
| David | 1 | | 2012/01/19 | |1|
| David | 2 | | 2012/01/20 | |2|
| David | 2 | | 2012/01/21 | |1|
| David | 2 | | 2012/01/22 | |2|
| David | 2 | | 2012/01/23 | |1|
| David | 3 | | 2012/01/24 | |2|
| David | 3 | | 2012/01/25 | |1|
| John | 1 | | 2012/01/19 | |1|
| John | 1 | | 2012/01/20 | |2|
| John | 1 | | 2012/01/21 | |1|
| John | 2 | | 2012/01/22 | |2|
| John | 2 | | 2012/01/23 | |1|
I want the result to look like this
| User | Email | | Time| |ID|
| David | 1 | | 2012/01/19 | |1|
| David | 2 | | 2012/01/20 | |2|
| David | 3 | | 2012/01/24 | |2|
| John | 1 | | 2012/01/19 | |1|
| John | 2 | | 2012/01/22 | |2|
What would be a good way to do this in MySQL? Distinct wouldn't work since it applies to all rows. I tried ROW_NUMBER() OVER (PARTITION BY Email ORDER BY Time DESC) rnm but this also doesn't work, as if you do rnm = 1 it ignores all the following emails (and rnm between 1 and 10 would return duplicates). I'm not sure if there's a way to group this based on a different email from the same user
You need to PARTITION BY User, Email. Also, to get the first occurrence, you need to order ascending, not descending.
WITH t AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY User, Email ORDER BY Time ASC) AS rn
FROM yourTable
)
SELECT User, Email, Time, ID
FROM t
WHERE rn = 1
DEMO
You would only need the window function if you want other columns from the same row as the minimum time.
Related
Hi guys i have a problem displaying a data from my query code.
I want to display a data from the closest date today. Below is my sample data and my output data that i want to display.
Landing Area data
|landing_id| id_number| address |
---------------------------------
| 1 | 00012345 | Ozamiz |
| 2 | 00012346 | Tudela |
| 3 | 00012347 | Nailon |
| 4 | 00012348 | Taboo |
| 5 | 00012349 | Jimenez |
| 6 | 00012350 | Tangub |
---------------------------------
Percentage data
|percent_id| landing_id | percentage | date_added |
-----------------------------------------------------------
| 1 | 1 | 9 |2018-10-08 21:42:22 |
| 2 | 1 | 12 |2018-10-03 20:43:32 |
| 3 | 1 | 43 |2018-10-15 19:43:49 |
| 4 | 3 | 22 |2018-10-10 15:43:56 |
| 5 | 3 | 77 |2018-10-12 18:44:03 |
-----------------------------------------------------------
And this is my query code.
SELECT fish_landing.landing_id,
percentage.landing_id as percentage_landing_id,
percentage.percentage,
percentage.date_added
FROM percentage
RIGHT OUTER JOIN fish_landing ON percentage.landing_id = fish_landing.landing_id
ORDER BY fish_landing.landing_id ASC
The output of my code is this, where the date_added and the percentage is not exact.
|percent_id| percentage | date_added |
----------------------------------------------
| 1 | 9 |2018-10-08 21:42:22 |
| 2 | | |
| 3 | 22 |2018-10-10 15:43:56 |
| 4 | | |
| 5 | | |
| 6 | | |
----------------------------------------------
And the output data that I want to display is the table below, where the percentage that has a latest date_added in every landing_id will be display.
|landing_id| percentage | date_added | address |
--------------------------------------------------------
| 1 | 43 |2018-10-15 19:43:49 | Ozamiz |
| 2 | | | |
| 3 | 77 |2018-10-12 18:44:03 | Nailon |
| 4 | | | |
| 5 | | | |
| 6 | | | |
--------------------------------------------------------
I hope you can help me in my problem.
You can get maximum date_added for a landing_id in a separate derived table and use it for joining.
Try the following:
SELECT fish_landing.landing_id,
percentage.percentage,
percentage.date_added,
fish_landing.address
FROM fish_landing
LEFT JOIN percentage ON percentage.landing_id = fish_landing.landing_id
LEFT JOIN (SELECT landing_id, MAX(date_added) AS max_date_added
FROM percentage
GROUP BY landing_id) AS dt
ON dt.landing_id = percentage.landing_id AND
dt.max_date_added = percentage.date_added
ORDER BY fish_landing.landing_id ASC
I'm trying to run a report on User ACL's. We use MYSQL and my we're prohibited from using subqueries for performance reasons. The goal is to turn this:
--------------------------------
| userName | folderID | roleID |
--------------------------------
| gronk | 1 | 1 |
| gronk | 2 | 2 |
| gronk | 4 | 2 |
| tbrady | 1 | 2 |
| jedelman | 1 | 1 |
| jedelman | 2 | 1 |
| mbutler | 1 | 2 |
| mbutler | 2 | 2 |
| bill | 1 | 3 |
| bill | 2 | 3 |
| bill | 3 | 3 |
| bill | 4 | 3 |
--------------------------------
Into this:
------------------------
| Lowest Role | Number |
------------------------
| 1 | 2 |
| 2 | 2 |
| 3 | 1 |
------------------------
I can see how to do it with a subquery. The inner query would do a group by on userName with a min(roleID). Then the outer query would do a group by on the lowest role and count(*). But I can't see how to do it without a subquery.
Also, if it helps I created a SQL Fiddle that has the data above.
I found a solution using a left join:
select UFM.roleID, count(distinct UFM.userName)
from UserFolderMembership UFM
left join UserFolderMembership UFM2 on
UFM.userName = UFM2.userName and
UFM.roleID > UFM2.roleID
where
UFM2.userName is null
group by
UFM.roleID
I've got a table that looks like this:
+----+--------------------------------+
| id | slug |
+----+--------------------------------+
| 1 | gift |
| 1 | psychological-manipulation |
| 1 | christmas |
| 1 | giving |
| 1 | the-town-santa-forgot |
| 1 | santa-claus |
| 1 | mp3 |
| 1 | christmas |
| 2 | entertainment-culture |
| 2 | christmas |
| 2 | culture |
| 2 | literature |
| 2 | christmas-music |
| 2 | christmas-window |
| 2 | broadcasting-nec |
| 2 | how-the-grinch-stole-christmas |
| 2 | the-polar-express |
| 2 | banker |
| 2 | christmas |
| 2 | potter |
| 2 | christmas-eve |
| 2 | bailey |
| 2 | its-a-wonderful-life |
| 2 | the-polar-express |
| 2 | disney |
| 2 | tim-burton |
| 2 | a-christmas-carol |
| 2 | the-nightmare-before-christmas |
| 2 | chuck-jones |
+----+--------------------------------+
I want to get unique ids from the table where at least two of a list of slugs match for a given id.
For example lets say I've got the slugs values of:
gift
christmas
giving
I would want all unique ids that have a matching record for at least 2 of those.
i.e. only an id that had both the gift AND christmas slug or the giving AND christmas slug or the gift AND giving slug, etc...
You can use the distinct modifier to count the number of different slugs per ID:
SELECT id
FROM mytable
WHERE slug IN ('gift', 'christmass', 'giving')
GROUP BY id
HAVING COUNT(DISTINCT slug) >= 2
I have the following table:
TABLE sales
| id | name | date | amount |
|----|------|------------|--------|
| 1 | Mike | 2016-12-05 | 67.15 |
| 2 | Mike | 2016-12-09 | 98.24 |
| 3 | John | 2016-12-12 | 12.98 |
| 4 | Mike | 2016-12-19 | 78.48 |
| 5 | Will | 2016-12-19 | 175.26 |
| 6 | John | 2016-12-22 | 14.26 |
| 7 | John | 2016-12-23 | 13.48 |
I am trying to create a view that will group by the name column and return only the most resent amount. It should look like this:
TABLE sales_view
| id | name | date | amount |
|----|------|------------|--------|
| 4 | Mike | 2016-12-19 | 78.48 |
| 5 | Will | 2016-12-19 | 175.26 |
| 7 | John | 2016-12-23 | 13.48 |
I'm not sure how to go about making this. I would imagine I would need sub-queries, but I know that SQL get mad if you try to use them inside of views.
You can use a tuple and a subquery with group by for max(date)
select * from sales
where (name, date) in ( select name, max(date)
from sales
group by name)
I'm trying to figure out a good way of doing an SQL query that returns a table of user names and their choices (there are a set number of choices and a user can have many choices) as in the example below. I haven't been able to find a good simple example of this (other than how the relationship is laid out). Is this solution viable or is there a better way of doing it? I seem to get the table I'm looking for.
SELECT
users.name,
choices.choice as choice
FROM
choice
JOIN relation ON choice.choice_id = relation.choice_id
JOIN users ON users.name_id = relation.user_id;
Gives me the correct table:
+------+--------+
| name | choice |
+------+--------+
| amy | a |
| amy | b |
| amy | c |
| joe | d |
+------+--------+
The simple database looks like this:
Users
+------+---------+
| name | name_id |
+------+---------+
| amy | 1 |
| joe | 2 |
+------+---------+
Choices
+----------+---------+
| choice_id| choice |
+----------+---------+
| 1 | a |
| 2 | b |
| 3 | c |
| 4 | d |
+----------+---------+
Relation
+----------+---------+
| choice_id| user_id |
+----------+---------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
+----------+---------+