order without duplicates - mysql

I have a table as follows:
ident_nr|proj_nr|start_time|
----------------------------
05.26.73|0000001|1116936920|
09.56.df|0000002|1213431234|
11.ac.12|0000003|1236485758|
98.er.df|0000001|1287789755|
70.12.5n|0000001|1011245554|
33.dt.vp|0000003|1239125544|
And I want a result like this:
ident_nr|proj_nr|start_time|
----------------------------
98.er.df|0000001|1287789755|
09.56.df|0000002|1213431234|
33.dt.vp|0000003|1239125544|
where proj_nr is in asc order and start time with the max value.
Note: ident_nr is unique and proj_nr could have multiple ident_nr.
Database: MySQL.
Is there an SQL query that could achieve this result?
Thanks

SELECT t.ident_nr, t.proj_nr, t.start_time
FROM YourTable t
INNER JOIN (SELECT proj_nr, MAX(start_time) AS MaxTime
FROM YourTable
GROUP BY proj_nr) q
ON t.proj_nr = q.proj_nr
AND t.start_time = q.MaxTime
ORDER BY t.proj_nr;

SELECT t1.*
FROM table AS t1
INNER JOIN (
SELECT proj_nr, MAX(start_time) AS MaxTime
FROM table
GROUP BY proj_nr) AS t2
ON (t1.proj_nr = t2.proj_nr AND t1.start_time = t2.MaxTime)
Your criteria seems to be MAX(start_time) in your sample data. If not, please be more detailed in your question about what you want.

Related

How to perform calculations on queries in mysql that return multiple values

First query:
SELECT COUNT(sales.ucid) AS totalOutcomes
FROM sales
group by date(sales.saleDate)
Second query:
SELECT COUNT(*) AS joinedOutcomes
FROM sales
JOIN calls
ON sales.ucid = calls.call_id
group by date(sales.saleDate)
I now want to use the output from the second query and divide that by the output from the first query.
Can someone please help with this? Thanks!
Join the two queries.
SELECT t1.date, joinedOutcomes/totalOutcomes
FROM (
SELECT date(sales.saleDate) AS date, COUNT(sales.ucid) AS totalOutcomes
FROM sales
GROUP BY date
) AS t1
JOIN (
SELECT date(sales.saleDate) AS date, COUNT(*) AS joinedOutcomes
FROM sales
JOIN calls ON sales.ucid = calls.call_id
group by date
) AS t2 ON t1.date = t2.date

SQL query to fetch rows which has same IDs but different values in other columns

I am Using the below table
The case_id for two rows. If the case Id is same then I would want to fetch the row that has Test_script_type as automation and ignore the manual. How can I achieve it with a SQL query..If there is only manual fetch the manual row. How can I achieve it with a SQL query. The Output would be like :
Help is appreciated. Thanks for your time In-advance
You could adress this with not exists:
select t.*
from mytable t
where
script_type = 'Automation'
or not exists (
select 1
from mytable t1
where
t1.case_id = t.case_id
and t1.script_name <> t.script_name
and t1.script_type = 'Automation'
)
You can also filter with a correlated subquery:
select t.*
from mytable t
where t.script_type = (
select min(t1.script_type) -- This gives priority to 'Automation' against 'Manual'
from mytable t1
where t1.case_id = t.case_id
)
SELECT t1.*
FROM `table` t1
LEFT JOIN `table` t2 ON t1.case_id = t2.case_id AND t1.script_type != t2.script_type
WHERE t1.script_type = 'automation' OR t2.case_id IS NULL
You could do something like the following:
WITH cte AS (
SELECT T1.CASE_ID, T1.SCRIPT_NAME, T1.SCRIPT_TYPE,
COUNT(T1.CASE_ID) OVER (PARTITION BY T1.CASE_ID) AS cnt
FROM table1 T1
)
SELECT cte.CASE_ID, cte.SCRIPT_NAME, cte.SCRIPT_TYPE
FROM cte
WHERE (cte.cnt > 1 AND UPPER(cte.SCRIPT_TYPE) = UPPER('AUTOMATION'))
OR cte.cnt = 1
The WITH statement adds a column counting how many times the case_id value is duplicated, which helps identify the rows you want to work with.
Here is an example of it working with the data you have provided: SQLFiddle
If you are using MSSQL Server, You may try below query -
SELECT *
FROM (SELECT CASE_ID, SCRIPT_NAME, SCRIPT_TYPE, ROW_NUMBER() OVER(PARTITION BY CASE_ID ORDER BY SCRIPT_TYPE) RN
FROM YOUR_TAB) T
WHERE RN = 1

MySQL Get exactly one entry per id by multiple ids

my problem is that I want this:
SELECT * FROM table
WHERE userId = 7243
ORDER BY date desc LIMIT 1
But for multiple ids in one request.
I tried this:
SELECT * FROM table
WHERE userId IN (7243, 1)
GROUP BY userId
ORDER BY date desc
But the order by seems to be ignored. Do anyone has a solution for me? Thank you
If you want the max date record for each of the two IDs, then you may use a subquery:
SELECT t1.*
FROM yourTable t1
INNER JOIN
(
SELECT userId, MAX(date) AS max_date
FROM yourTable
WHERE userId IN (7243, 1)
GROUP BY userId
) t2
ON t1.userId = t2.userId AND t1.date = t2.max_date
WHERE
t1.userId IN (7243, 1);
This is the just greatest-value-per-group question with a slight twist, namely that you only want to see two of the possible groups in the output.
As #Raymond commented below, an index on (userId, date) should greatly speed up the t2 subquery. I am not sure if this index would help beyond that, but it should make a difference.

MySQL take rows and override ones without user_id

I have table like this one:
I would like to all rows, but if there is user_id 5 if this case, override other rows which have no user_id.
I tried both with MAX(user_id) and GROUP BY country_name, but it still returns, wrong results.
Final result I'm expecting:
Try this;)
select t1.*
from yourtable t1
inner join (
select max(user_id) as user_id, country_name from yourtable group by country_name
) t2 on t1.country_name = t2.country_name and t1.user_id = t2.user_id
This is just a solution based on your sample data. If you have a variety of user_id, it should be more different.
As of SQL Select only rows with Max Value on a Column you can easily get rows with max value on a column by using both MAX(column) and GROUP BY other_column in one statement.
But if you want to select other columns too, you have to this in a subquery like in the following example:
SELECT a.*
FROM YourTable a
INNER JOIN (
SELECT country_name, MAX(user_id) user_id
FROM YourTable
GROUP BY country_name
) b ON a.country_name = b.country_name AND a.user_id = b.user_id

what should be the mysql query to fetch recently added message by a group of users which are stored in the same table

I have the following table structure
and i want the result to be
Here is the query which i tried
select * from table where userid IN(201,202,203,204,205)
group by userid
order by messageid desc
But i dint get the latest records based on messageid.
I need to write this in a single query as i must use order by clause
Please explain my mistake and provide a solution
You can join the table to itself using the max of the messageid if I'm understanding your question correctly:
select t.messageid, t.userid, t.data
from yourtable t
join (
select max(messageid) maxmessageid, userid
from yourtable
where userid in (201,202,203,204,205)
group by userid
) t2 on t.userid = t2.userid and t.messageid = t2.maxmessageid
order by t.messageid desc
SQL Fiddle Demo
Edit: Here's an alternative approach using IN:
select messageid, userid, data
from yourtable
where messageid in (
select max(messageid) maxmessageid
from yourtable
where userid in (201,202,203,204,205)
group by userid
)
order by messageid desc
More Fiddle
SELECT yourtable.*
FROM
yourtable INNER JOIN (SELECT userid, MAX(messageid) max_messageid
FROM yourtable
WHERE userid IN (201,202,203,204,205)
GROUP BY userid) mx
ON yourtable.messageid=mx.max_messageid
AND yourtable.userid=mx.userid