I have two tables, one is Table_Log for when user will update the data then it will stored one data into Table_Log, and another table is main registration table: Table_Registration and I need based on updatedDate of Table_Log data should come first order by desc.
Table_Log:
RegId Name updatedDate
-----------------------------------
3 jj 2018-03-21 13:30:04.497
3 jj 2018-03-20 13:30:04.497
Table_Registration
RegId Name Email SubDate
--------------------------------------------------------
2 kk kk#gmail.com 2018-03-01 15:30:04.497
3 jj jj#gmail.com 2018-02-26 15:30:04.497
1 Raj raj#gmail.com 2018-02-30 13:30:04.497
I need this output as my result:
RegId Name Email SubDate
--------------------------------------------------------
3 jj jj#gmail.com 2018-02-26 15:30:04.497
2 kk kk#gmail.com 2018-03-01 15:30:04.497
1 Raj raj#gmail.com 2018-02-30 13:30:04.497
I tried below query but some duplication is coming.
select r.*
from Table_Registration r
left join Table_Log a
on a.RegId = r.RegId
order by isnull(a.updatedDate, r.SubDate) desc
select r.*
from Table_Registration r
left join Table_Log a
on a.RegId = r.RegId
order by isnull(a.updatedDate, r.SubDate) desc
In the above code, you left join to Table Log. This will give you one row per row of tablelog, which is why you are getting duplication. You need to process table_Log in some way so that you are only getting the most recent row per registration, and then join to that. Something like this
select r.*
from Table_Registration r
left join (Select RegId, Max(updateDate) as updateDate from Table_Log Group By RegId) a
on a.RegId = r.RegId
order by isnull(a.updatedDate, r.SubDate) desc
Related
i am new to sql and need help with a query. I have two tables user and user_family which contains data like
USER
ID
Date-Of-birth
User_Id
1
2021-05-21
28371
2
2021-04-17
28372
USER_FAMILY
ID
family_detail_id
User_Id
1
1
28371
2
1
28374
3
1
28375
4
2
28372
5
2
28373
6
2
28378
7
2
28379
i want to run a query which checks if current date in equal to someones dob in my user table, if yes i want to return all entries from user_family table which has same family_detail_id to someone whose dob has been matched.
Suppose if the current date is 2021-05-21 then the result should be,
ID
family_detail_id
User_Id
dob
birthday_user_id
2
1
28374
2021-05-21
28371
3
1
28375
2021-05-21
28371
You can use a self-join on the family_detail_id,
select f2.*
from user u join user_family f on f.id=u.id
join user_family f2 on f2.family_detail_id=f.family_detail_id
where u.Date_Of_birth=currdate();
Working Fiddle
I would suggest exists. Assuming that user.id matches to user_family.family_detail_id, then this looks like:
select uf.*
from user_family uf
where exists (select 1
from user u
where u.family_detail_id = u.id and
u.dob = curdate()
);
You may try below query, assuming USER_ID is the linking column between the two tables -
select uf1.*
from user_family uf1
where uf1.family_detail_id in
(select uf.family_detail_id
from user_family uf
inner join user u on u.user_id = uf.user_id
where u.Date-Of-birth = CURDATE()); --DATE(u.Date-Of-birth) = CURDATE()
HTH!
I have two tables like this
rooms
id | number
1 | 111
2 | 112
occupied_rooms
id | check_in | check_out | room_id
1 | 2017-10-01 | 2017-10-04 | 1
I want to get all the unoccupied rooms according to date check_in and check_out for this I tried
select r.id
, r.number
from rooms r
left join occupied_rooms o
on r.id = o.room_id
where (o.check_in not between "2017-10-05" and "2017-10-08" )
or (o.check_in >= "2017-10-05" and o.check_out <= "2017-10-08"))
but this query giving me result like this. which is incorrect.
id | number
1 | 111
What is wrong with this query?
Thank you for your any help and suggestions
Just join the two tables on the condition that the id matches and the range of intended stay overlaps with the range in the occupied_rooms table.
SELECT r.*
FROM rooms r
LEFT JOIN occupied_rooms t
ON r.id = t.id AND
('2017-10-02' <= t.check_out AND '2017-10-03' >= t.check_in)
WHERE
t.id IS NULL; -- NULL value indicates the room did not overlap
-- with any existing reservations
You can also check out this great reference question on how to deal with overlapping ranges in SQL queries. It makes the problem you are facing much simpler.
Demo
Your data in table occupied_rooms meets the first condition in "where";
check_in date(2017-10-01) is not between "2017-10-05" and "2017-10-08" and your where is or.
Thus, the result is included this data.
Can you tell us what output you expect?
I have searched this site and others but cannot find any help with this problem. Maybe I am making this more difficult than necessary.
I have two tables as follows. I want to return all the information for each item but only the most recent data and include data from both tables
table 1: serviceRequestSubmission
sid customerID
1001 11111
1002 22222
1003 33333
1004 44444
1005 55555
table 2: serviceRequestHistory
historyID requestID statusUpdate
1 1001 Assigned
2 1002 Assigned
3 1003 Pending
4 1004 Delayed
5 1002 Pending
6 1002 Closed
I want to return:
sidID historyID statusUpdate
1001 1 Assigned
1002 6 Closed
1003 3 Pending
1004 4 Delayed
1005 - Submitted
I have tried the following code but it returns all the rows of data but I only want the most recent/highest historyID.
SELECT serviceRequestSubmissions.*, serviceRequestHistory.*
FROM serviceRequestSubmissions
LEFT JOIN serviceRequestHistory ON serviceRequestSubmissions.sid = serviceRequestHistory.requestID
ORDER BY serviceRequestSubmissions.sid DESC
Any help would be appreciated.
Thank you!
SELECT serviceRequestSubmissions.*, serviceRequestHistory.*
FROM serviceRequestSubmissions
LEFT JOIN serviceRequestHistory
ON serviceRequestSubmissions.sid = serviceRequestHistory.requestID
AND historyID IN (
SELECT max(historyID)
FROM serviceRequestHistory
GROUP BY requestID
)
ORDER BY serviceRequestSubmissions.sid DESC
EDIT:
Only closed:
SELECT serviceRequestSubmissions.*, serviceRequestHistory.*
FROM serviceRequestSubmissions
JOIN serviceRequestHistory
ON serviceRequestSubmissions.sid = serviceRequestHistory.requestID
AND historyID IN (
SELECT max(historyID)
FROM serviceRequestHistory
WHERE statusUpdate = 'Closed'
GROUP BY requestID
)
ORDER BY serviceRequestSubmissions.sid DESC
Add a LIMIT clause at the end of the query:
LIMIT 2
You can use TIMESTAMP or id in your database and fetch record which has greatest TIMESTAMP or id value or with descending TIMESTAMP or id order by LIMIT clause
This is a common problem of type greatest-n-per-group. I think this is the best way to solve it:
SELECT
s.sid sidID,
IFNULL(h1.historyID,'-') historyID,
IFNULL(h1.statusUpdate,'Submitted') statusUpdate
FROM
serviceRequestSubmissions s
LEFT JOIN serviceRequestHistory h1 ON ( s.sid = h1.requestID )
LEFT JOIN serviceRequestHistory h2 ON ( s.sid = h2.requestID AND ( h1.historyID < h2.historyID OR h1.historyID = h2.historyID AND h1.requestID < h2.requestID ) )
WHERE
h2.requestID IS NULL
ORDER BY
s.sid
This is how it works: given a row of the table serviceRequestHistory, there shouldn't be any other row with the same requestID and a greater historyID (the conditions after the OR is to solve the ties). This kind of solution is usually better than using sub-selects.
I've got 3 tables - entryrecord, employee and employee_entryrecord (linking table).
The query I'd like is for it to return the most recent (max time) inout record for each employee.
employee
id employee
1 John
2 Tom
entryrecord
id created_date inout
1 2016-07-22 16:01:38 1
2 2016-07-22 16:03:22 1
3 2016-07-22 16:05:22 2
4 2016-07-22 16:07:22 2
5 2016-07-22 16:09:22 1
I'd like the follow output
created_date employee inout entryrecordid
2016-07-22 16:09:22 John 1 5
2016-07-22 16:05:22 Tom 2 3
However, in the sqlfiddle below you can see it does not return the correct inout and entryrecordid values.
I've created a sqlfiddle to view what I've done.
SQL Fiddle
Any help would be great.
Thanks.
Please give it a try:
SELECT
finalALias.created_date,
E.employee,
finalALias.inout,
finalALias.id AS entryrecordid
FROM employee E
INNER JOIN
(
SELECT
*
FROM entryrecord entryR
INNER JOIN
(
SELECT
EER.employeeid,
MAX(created_date) max_time
FROM entryrecord ER
INNER JOIN employee_entryrecord EER ON ER.id = EER.entryrecordid
GROUP BY EER.employeeid
) t
ON t.max_time=entryR.created_date
) AS finalALias
ON E.id = finalALias.employeeid
ORDER BY finalALias.created_date DESC;
WORKING DEMO
Just a gentle reminder:
E -> employee
ER -> entryrecord
ERR -> employee_entryrecord
The problem is that grouping happens before ordering. You will have to do a sub query. You always want to try and keep your sub queries to a minimum as they put a heavy toll on the SQL server.
I changed your LEFT JOINS to INNER JOINS because it looked like you wanted to only get employees that were in the other tables.
SELECT
entryrecord.created_date,
employee.employee,
entryrecord.inout,
entryrecord.id
FROM
entryrecord
INNER JOIN
employee_entryrecord ON entryrecord.id = employee_entryrecord.entryrecordid
INNER JOIN
employee ON employee_entryrecord.employeeid = employee.id
WHERE
entryrecord.inout in (1,2)
AND entryrecord.id = (
SELECT er2.id
FROM employee_entryrecord eer2, entryrecord er2
WHERE eer2.employeeid = employee.id
AND er2.id = eer2.entryrecordid
ORDER BY er2.created_date DESC LIMIT 1
)
I have two tables with a one to many relationship. I join the tables by an id column. My problem is that I need a count of all matching entries from the second (tablekey_id) table but I need the information from the row marked with the boolean is_basedomain. As a note there is only one row with is_basedomain = 1 per set of rows with the same tablekey_id.
Table: tablekey
id linkdata_id timestamp
22 9495028175 2013-03-10 01:13:46
23 8392740179 2013-03-10 21:23:25
Table: searched_domains.
NOTE: tablekey_id is the foreign key to the id in the tablekey table.
id tablekey_id domain is_basedomain
1 22 somesite.com 1
2 22 yahoo.com 0
3 23 red.com 1
4 23 blue.com 0
5 23 green.com 0
Heres the query Im working with. I was trying to use a sub query but I cant seem to select only the count for the current tablekey_id so this does not work.
SELECT `tablekey_id`, `linkdata_id`, `timestamp`, `domain`, `is_basedomain`,
(SELECT COUNT(1) AS other FROM `searched_domains` AS dd
ON dd.tablekey_id = d.tablekey_id GROUP BY `tablekey_id`) AS count
FROM `tablekey` AS k
JOIN `searched_domains` AS d
ON k.id = d.tablekey_id
WHERE `is_basedomain` = 1 GROUP BY `tablekey_id`
The result that I would like to get back is:
tablekey_id linkdata_id timestamp domain is_basedomain count
22 9495028175 2013-03-10 01:13:46 somesite.com 1 2
23 8392740179 2013-03-10 21:23:25 red.com 1 3
Can anyone help me get this into one query?
You can treat the searched_domains rows that have is_basedomain=1 as a separate table in the query and join it with another instance of searched_domains (to get the count):
SELECT
d.tablekey_id,
k.linkdata_id,
k.timestamp,
d.domain,
d.is_basedomain,
COUNT(*) as 'count'
FROM
tablekey AS k
join searched_domains AS d on d.tablekey_id=k.id
join searched_domains AS d2 on d2.tablekey_id=d.tablekey_id
WHERE
d.is_basedomain = 1
GROUP BY
d.tablekey_id,
k.linkdata_id,
k.timestamp,
d.domain,
d.is_basedomain
you have an error when using ON instead use WHERE
try this
SELECT `tablekey_id`, `linkdata_id`, `timestamp`, `domain`, `is_basedomain`,
(SELECT COUNT(1) AS other FROM `searched_domains` AS dd
where dd.tablekey_id = d.tablekey_id GROUP BY `tablekey_id`) AS count
FROM `tablekey` AS k
JOIN `searched_domains` AS d
ON k.id = d.tablekey_id
WHERE `is_basedomain` = 1 GROUP BY `tablekey_id`
DEMO HERE
There is no reason to use subquery, or what is your opinion?
SELECT
`tablekey_id`,
`linkdata_id`,
`timestamp`,
`domain`,
`is_basedomain`,
COUNT(*) as count
FROM
`tablekey` AS k ,
`searched_domains` AS d
WHERE
k.id = d.tablekey_id AND
`is_basedomain` = 1
GROUP BY
`tablekey_id`,
`linkdata_id`,
`timestamp`,
`domain`,
`is_basedomain`
If you want only latest timestamp use MAX(timestamp) as timestamp and remove it from group by.