select max id from current id mysql - mysql

Given the database.....
ID Name item_order Manager
1 ted 2 N
2 bob 5 N
3 tony 1 Y
4 fred 3 N
5 william 4 N
6 george 6 Y
7 cade 8 N
8 matt 7 N
I would like to be able to select managers Id prior to the current non managers name. So for example the result for bob would be tony or 3.
I can figure out how to do this with two requests
SELECT MAX( item_order) AS parent
FROM tablename WHERE item_order < 5 && Manager = 'Y'
The result from that I would make another select by the item_order. Is there a way to do this all in one select?

SELECT * FROM tablename
WHERE Manager = 'Y'
AND item_order = (SELECT MAX(item_order) AS parent
FROM tablename
WHERE item_order < 5
AND Manager = 'Y') AS t

SELECT
n.*,
ManagerName = m.Name
FROM tablename n
LEFT JOIN tablename m ON m.Manager = 'Y' AND n.item_order > m.item_order
LEFT JOIN tablename m2 ON m2.Manager = 'Y'
AND m2.item_order < n.item_order AND m2.item_order > m.Item_order
WHERE n.Manager = 'N'
AND m2.ID IS NULL
This will give you the list of all non-managers together with the names of those managers that directly precede them (based on item_order).
If you only want to return one row for a specific non-manager, add one more condition like this:
AND n.Name = 'bob'

Related

SQL Query - Find Duplicates with a Different Key

I have the following data:
id userid name group
1 1 A x
2 1 A y
3 1 A z
4 2 B x
5 2 B y
6 3 C y
7 4 D x
8 5 E x
9 5 E z
10 6 F x
I want to find those records that meet all this condition:
Select all rows where the a userid belongs to a group other than y but the userid also belongs to group y.
The resulting dataset will be as follows:
id userid name group
1 1 A x
3 1 A z
4 2 B x
If you see, it has resulted in two records for userid a because these are two two records belong to groups other than y but the userid 1 also belongs to group y. Same for userid 2.
I have been breaking my head on how to get this in an SQL statement but not even close to a solution.
Any help is appreciated.
Use a join:
SELECT t1.*
FROM mytable t1
INNER JOIN mytable t2
ON t1.user_id = t2.user_id AND t1.group <> t2.group AND t2.group = 'y'
I think that would be the fastest query (but please feel free to try the other solutions as well).
Add an index on user_id if not already there and maybe play with some other indexes as well (maybe a composite index on group and user_id can be utilized)
Use exists
select *
from MyTable a2
where name_group <> 'y'
and exists (select 1
from MyTable a2
where a2.name_group = 'y'
and a2.userid = a1.userid)
You can get all the users that meet the condition using aggregation and having:
select userid
from t
group by userid
having sum( group = 'y' ) > 0 and
sum( group <> 'y') > 0;
I leave it to your to put this into a query to get all the original rows.

How do you add two values from the same table and store in calculated record in the same table?

Hi I have one tables here:
equipment
ID, Owner, Type, Count
1 Bob phone 10
2 Larry computer 11
1 Bob computer 11
What I am trying to do is add the computers that Bob, with id 1, to the computers of Larry's, with id 2. I'm trying to increase the count. The count should be 11+11=22. The new computer count for id 2 should be 22 and should update like this in the database:
equipment
ID, Owner, Type, Count
1 Bob phone 10
2 Larry computer 22
1 Bob computer 11
If Bob did not have any computer, meaning there was no record with ID = 2, then the record should be created.
Here is my SQL:
INSERT INTO EQUIPMENT(`ID`, `OWNER`, `TYPE`, `COUNT`)
SELECT 1 as t.ID, t.OWNER, t.TYPE, t.COUNT
FROM EQUIPMENT t
WHERE t.ID = 2
on duplicate key
update
COUNT = COUNT + t.COUNT;
Why are you using insert to update a row?
update equipment e cross join
(select e1.* from equipment e1 where e1.id = 1) as e1
select e.count = e.count + e1.count
where e.id = 2;
Some thing like this
UPDATE Yourtable a
JOIN Yourtable b
ON a.NAME = b.NAME
AND a.ID = b.ID + 1
SET a.Count = a.Count + b.Count

Filter count table query

i have 2 tables as following.
User
id name
---------------
1 john
2 raju
3 manu
4 raghu
friendtable
id userid recvId
------------------------
1 1 2
2 1 3
3 2 3
4 3 4
Is it possible to filter users by their friends count from these tables.Please help me.
For eg :- range >=3 will result : john,manu
range >3 and range <2 will result : raju
range <2 result : raghu
Do a UNION ALL to get all id's from friendstable in one column. Join users table with that result.
Do a GROUP BY, adjust HAVING to decide what to return, e.g. at least 3 times etc.
select u.name
from users
join (select userid as id from friendtable
union all
select recvId as id from friendtable) f
on u.id = f.id
group by u.name
having count(*) >= 3
SELECT name FROM user a,friendtable b WHERE a.id=b.id AND b.recvid>=3
SELECT name FROM user a,friendtable b WHERE a.id=b.id and b.recvid>3 AND b.recid<2
SELECT name FROM user a,friendtable b WHERE a.id=b.id AND b.recid<2

MySQL query matching multiple fields?

I'm confused on how to write the following query in MySQL: Given one collaborator, I'd like to get all the collaborators that participated on each item that this collaborator worked on.
Here's my collaborators table:
id collaborator_id item_id
1 1 1
2 2 1
3 3 1
4 4 2
5 1 2
6 2 3
for collaborator_id=1, the query would return:
collaborator_id item_id
1 1
2 1
3 1
1 2
4 2
So collaborator_id=1 worked with collaborator_ids=2,3 on item_id=1 and worked by themselves on item_id=2.
This seems super simple but I'm having a brain freeze on how to get these results. Thoughts?
This query joins on the item_id and gets you all the unique collaborators who worked with a given collaborator on shared items, other than the collaborator himself:
SELECT distinct b.collaborator_id, b.item_id
FROM collab_table a
JOIN collab_table b
on a.item_id = b.item_id
WHERE a.collaborator_id = 1
and b.collaborator_id != 1
you can use subquery
SELECT *
FROM collaborator
WHERE item_ID IN
(
SELECT item_ID
FROM collaborator
WHERE collaborator_id = 1
)
ORDER BY item_ID, Collaborator_ID
or by using JOIN
SELECT a.*
FROM COLLABORATOR a
JOIN COLLABORATOR b
ON a.ITEM_ID = b.ITEM_ID
WHERE b.COLLABORATOR_ID = 1
ORDER BY item_ID, Collaborator_ID;
SQLFiddle Demo
What you need to do is join the table back to itself, using your filter on one of the aliases, and pulling the result set from the other:
select a.COLLABORATOR_ID, a.ITEM_ID
from COLLABORATOR as a
inner join COLLABORATOR as b on
a.ITEM_ID = b.ITEM_ID
where b.COLLABORATOR_ID = 1

SQL: finding differences between rows

I want to count how many times each user has rows within '5' of eachother.
For example, Don - 501 and Don - 504 should be counted, while Don - 501 and Don - 1600 should not be counted.
Start:
Name value
_________ ______________
Don 1235
Don 6012
Don 6014
Don 6300
James 9000
James 9502
James 9600
Sarah 1110
Sarah 1111
Sarah 1112
Sarah 1500
Becca 0500
Becca 0508
Becca 0709
Finish:
Name difference_5
__________ _____________
Don 1
James 0
Sarah 2
Becca 0
Use the ABS() function, in conjunction with a self-join in a subquery:
So, something like:
SELECT name, COUNT(*) / 2 AS difference_5
FROM (
SELECT a.name name, ABS(a.value - b.value)
FROM tbl a JOIN tbl b USING(name)
WHERE ABS(a.value - b.value) BETWEEN 1 AND 5
) AS t GROUP BY name
edited as per Andreas' comment.
Assuming that each name -> value pair is unique, this will get you the count of times the value is within 5 per name:
SELECT a.name,
COUNT(b.name) / 2 AS difference_5
FROM tbl a
LEFT JOIN tbl b ON a.name = b.name AND
a.value <> b.value AND
ABS(a.value - b.value) <= 5
GROUP BY a.name
As you'll notice, we also have to exclude the pairs that are equal to themselves.
But if you wanted to count the number of times each name's values came within 5 of any value in the table, you can use:
SELECT a.name,
COUNT(b.name) / 2 AS difference_5
FROM tbl a
LEFT JOIN tbl b ON NOT (a.name = b.name AND a.value = b.value) AND
ABS(a.value - b.value) <= 5
GROUP BY a.name
See the SQLFiddle Demo for both solutions.
Because the OP also wants de zero counts, we'll need a self- left join. Extra logic is needed if one person has two exactly the same values, these should also be counted only once.
WITH cnts AS (
WITH pair AS (
SELECT t1.zname,t1.zvalue
FROM ztable t1
JOIN ztable t2
ON t1.zname = t2.zname
WHERE ( t1.zvalue < t2.zvalue
AND t1.zvalue >= t2.zvalue - 5 )
OR (t1.zvalue = t2.zvalue AND t1.ctid < t2.ctid)
)
SELECT DISTINCT zname
, COUNT(*) AS znumber
FROM pair
GROUP BY zname
)
, names AS (
SELECT distinct zname AS zname
FROM ztable
GROUP BY zname
)
SELECT n.zname
, COALESCE(c.znumber,0) AS znumber
FROM names n
LEFT JOIN cnts c ON n.zname = c.zname
;
RESULT:
DROP SCHEMA
CREATE SCHEMA
SET
CREATE TABLE
INSERT 0 14
zname | znumber
-------+---------
Sarah | 3
Don | 1
Becca | 0
James | 0
(4 rows)
NOTE: sorry for the CTE, I had not seen th mysql tag,I just liked the problem ;-)
SELECT
A.Name,
SUM(CASE WHEN (A.Value < B.Value) AND (A.Value >= B.Value - 5) THEN 1 ELSE 0 END) Difference_5
FROM
tbl A INNER JOIN
tbl B USING(Name)
GROUP BY
A.Name