SQLite: Alternative for UPDATE JOIN subquery - sqlite

I have the following SELECT query in SQLite. I'm struggling to figure out how to convert this to a SQLite-friendly UPDATE statement though... I know SQLite UPDATE does not support JOIN. Thank you!
The query is finding the most recent/maximum date for each employee and adding a column with that date to each individual employee
SELECT
emp.*, maxdate
FROM
employees emp JOIN (
SELECT name as newname, MAX(enddate) AS maxdate
FROM
employees
GROUP BY name) m
ON emp.name = m.newname
ORDER BY maxdate DESC;

Hmm, if I understand correctly, what you want is
UPDATE employees
SET enddate = (
SELECT MAX(enddate)
FROM employees e2
WHERE e2.name = employees.name
);

Related

Getting a min(date) AND max(date) AND their respective titles

I have three tables that I would like to select from
Table 1 has a bunch of static information about a user like their idnumber, name, registration date
Table 2 has the idnumber of the user, course number, and the date they registered for the course
Table 3 has the course number, and the title of the course
I am trying to use one query that will select the columns mentioned in table 1, with the most recent course they registered (name and date registered) as well as their first course registered (name and date registered)
Here is what I came up with
SELECT u.idst, u.userid, u.firstname, u.lastname, u.email, u.register_date,
MIN(l.date_inscr) as mindate, MAX(l.date_inscr) as maxdate, lc.coursename
FROM table1 u,table3 lc
LEFT JOIN table2 l
ON l.idCourse = lc.idCourse
WHERE u.idst = 12787
AND u.idst = l.idUser
And this gives me everything i need, and the dates are correct but I have no idea how to display BOTH of the names of courses. The most recent and the first.
And help would be great.
Thanks!!!
You can get your desired results by generating the min/max date_inscr for each user in a derived table and then joining that twice to table2 and table3, once to get each course name:
SELECT u.idst, u.userid, u.firstname, u.lastname, u.email, u.register_date,
l.mindate, lc1.coursename as first_course,
l.maxdate, lc2.coursename as latest_course
FROM table1 u
LEFT JOIN (SELECT idUser, MIN(date_inscr) AS mindate, MAX(date_inscr) AS maxdate
FROM table2
WHERE idUser = 12787
) l ON l.idUser = u.idst
LEFT JOIN table2 l1 ON l1.idUser = l.idUser AND l1.date_inscr = l.mindate
LEFT JOIN table3 lc1 ON lc1.idCourse = l1.idCourse
LEFT JOIN table2 l2 ON l2.idUser = l.idUser AND l2.date_inscr = l.maxdate
LEFT JOIN table3 lc2 ON lc2.idCourse = l2.idCourse
As #BillKarwin pointed out, this is more easily done using two separate queries.

Update multiple rows from select statement

I am trying to assign 'A' to [Student Details].group based on this SELECT statement.
SELECT TOP (10) PERCENT [Person Id], [Given Names], Surname, Gpa, [Location Cd]
FROM [Student Details]
WHERE ([Location Cd] = 'PAR')
ORDER BY Gpa DESC
I can't figure out how to use a SELECT statement in an UPDATE statement.
Can someone please explain how to accomplish this?
I am using ASP .NET and MsSQL Server if it makes a difference.
Thanks
I'm assuming you want to update these records and then return them :
SELECT TOP (10) PERCENT [Person Id], [Given Names], Surname, Gpa, [Location Cd]
INTO #temp
FROM [Student Details]
WHERE ([Location Cd] = 'PAR')
ORDER BY Gpa DESC
update [Student Details] set group='A' where [person id] in(select [person id] from #temp)
select * from #temp
I'm also assuming person id is the PK of student details
Try this using CTE (Common Table Expression):
;WITH CTE AS
(
SELECT TOP 10 PERCENT [Group]
FROM [Student Details]
WHERE ([Location Cd] = 'PAR')
ORDER BY Gpa DESC
)
UPDATE CTE SET [Group] = 'A'
Is this you want?
Update top (10) Percent [Student Details] set [group] = 'A'
where [Location Cd] = 'PAR' AND [group] is null

SQL retrieving data NOT IN

SELECT ID, Name
FROM dbo.AmenitiesList
WHERE TypeID=#Type and Status = 'Available'
AND ID NOT IN
(SELECT AmenitiesID FROM dbo.ReservationList
WHERE Status = 'Cancelled' AND StartDate between #Arrival and #Departure
or EndDate between #Arrival and #Departure
or #Arrival between StartDate and EndDate
or #Departure between StartDate and EndDate)
This is my query, I want to display all the Available Amenities that the status is 'Cancelled' and the Arrival Date and Departure date is not between in the ArrivalDate and Departure date in Database. But when retrieving data, I didn't get the Amenities available because when the Status is cancelled it triggers the other condition about those in between dates. How to Avoid that?
I want to display Amenities that is Cancelled and also not between ArrivalDate and Departure Date
Thank you in advance guys!
For performance and optimization, consider table variables.
DECLARE #TABLE AS TABLE
(
AmenityID INT PRIMARY KEY CLUSTERED
)
INSERT INTO #TABLE
SELECT AmenitiesID FROM dbo.ReservationList
--Your conditions
--Get values that exist
SELECT * FROM AmentitiesList al
INNER JOIN #Table t on al.AmenityID = t.AmenityID
--Get values that don't
SELECT * FROM AmentitiesList al
LEFT JOIN #Table t on al.AmenityID = t.AmenityID
WHERE t.AmenityID IS NULL
Just because code is shorter, doesn't mean it scales. Left Joins are also a pain...
You could easily get rid of that too by using a table variable.
DECLARE #AmenityList AS TABLE
(
AmenityID INT PRIMARY KEY CLUSTERED
Matched BIT DEFAULT(0)
)
INSERT INTO #AmenityList
Select AmenityID FROM AmentitiesList
UPDATE #AmenityList SET Matched = 1
FROM #AmenitityList al
INNER JOIN #Table t on t.AmentityID = al.AmentityID
SELECT * FROM #AmentityList WHERE Matched = 0
How about this version?
SELECT ID, Name
FROM dbo.AmenitiesList
WHERE TypeID=#Type and Status = 'Available'
AND ID NOT IN
(SELECT AmenitiesID FROM dbo.ReservationList
WHERE Status = 'Cancelled' AND (StartDate between #Arrival and #Departure
or EndDate between #Arrival and #Departure
or #Arrival between StartDate and EndDate
or #Departure between StartDate and EndDate))
SELECT ID, Name
FROM dbo.AmenitiesList
WHERE TypeID=#Type and Status = 'Available'
AND ID NOT IN
(SELECT AmenitiesID FROM dbo.ReservationList
WHERE Status != 'Cancelled' AND Status != 'Check Out' AND ((#Arrival <= EndDate) AND (#Departure >= StartDate)))
This solve my problem! By the way thank you guys for spending time giving information to me! God Bless!

sqlite multiple table joining...how?

I have three tables doodhiya, doodhdata and cashdata.
I am trying to join these and fetch some needed data by this code but not succeed
SELECT dname,ddate,dmonth,dyear,dmilk,uid
FROM doodhiya
INNER JOIN doodhiya.dhid = doodhdata.ddhid
INNER JOIN doodhdata.dhid = cashdata.uid
WHERE (dname='$mik' AND dmonth='$mikdatem' AND dyear='$mikdatey')
ORDER BY ddate ASC
What I have to do?
You are missing the table name and the ON keyword in your join
SELECT dname,ddate,dmonth,dyear,dmilk,uid
FROM doodhiya
INNER JOIN doodhdata ON doodhiya.dhid = doodhdata.ddhid
INNER JOIN cashdata ON doodhdata.dhid = cashdata.uid
WHERE (dname='$mik' AND dmonth='$mikdatem' AND dyear='$mikdatey')
ORDER BY ddate ASC
A note on this part of the question:
Pls suggest me what I have to do
The syntax for a join is documented in the manual (and millions of SQL references in the web). So the best thing you can do the next time is to first consult the manual and/or a SQL reference.
SELECT retailername,
productname,
qty,
stock,
price,
discount
FROM temptablename,
productmaster,
retailermaster
WHERE temptablename.pid = productmaster.productid
AND temptablename.rid = retailermaster. retailercode
SELECT dname,
ddate,
dmonth,
dyear,
dmilk,
uid
FROM doodhdata,
cashdata
WHERE doodhiya.dhid = doodhdata.ddhid
AND doodhdata.dhid = cashdata.uid
AND dname='$mik'
AND dmonth='$mikdatem'
AND dyear='$mikdatey'
ORDER BY ddate ASC

Preventing Max function from using timestamp as part of criteria on a date column in PL/SQL

If I query:
select max(date_created) date_created
on a datefield in PL/SQL (Oracle 11g), and there are records that were created on the same date but at different times, Max() returns only the latest times on that date. What I would like to do is have the times be ignored and return ALL records that match the max date, regardless of their associated timestamp in that column. What is the best practice for doing this?
Edit: what I'm looking to do is return all records for the most recent date that matches my criteria, regardless of varying timestamps for that day. Below is what I'm doing now and it only returns records from the latest date AND time on that date.
SELECT r."ID",
r."DATE_CREATED"
FROM schema.survey_response r
JOIN
(SELECT S.CUSTOMERID ,
MAX (S.DATE_CREATED) date_created
FROM schema.SURVEY_RESPONSE s
WHERE S.CATEGORY IN ('Yellow', 'Blue','Green')
GROUP BY CUSTOMERID
) recs
ON R.CUSTOMERID = recs.CUSTOMERID
AND R.DATE_CREATED = recs.date_created
WHERE R.CATEGORY IN ('Yellow', 'Blue','Green')
Final Edit: Got it working via the query below.
SELECT r."ID",
r."DATE_CREATED"
FROM schema.survey_response r
JOIN
(SELECT S.CUSTOMERID ,
MAX (trunc(S.DATE_CREATED)) date_created
FROM schema.SURVEY_RESPONSE s
WHERE S.CATEGORY IN ('Yellow', 'Blue','Green')
GROUP BY CUSTOMERID
) recs
ON R.CUSTOMERID = recs.CUSTOMERID
AND trunc(R.DATE_CREATED) = recs.date_created
WHERE R.CATEGORY IN ('Yellow', 'Blue','Green')
In Oracle, you can get the latest date ignoring the time
SELECT max( trunc( date_created ) ) date_created
FROM your_table
You can get all rows that have the latest date ignoring the time in a couple of ways. Using analytic functions (preferrable)
SELECT *
FROM (SELECT a.*,
rank() over (order by trunc(date_created) desc) rnk
FROM your_table a)
WHERE rnk = 1
or the more conventional but less efficient
SELECT *
FROM your_table
WHERE trunc(date_created) = (SELECT max( trunc(date_created) )
FROM your_table)

Resources