SQL Select newest value Id from one table - sql

So we have an application that stores lap times for runners the tables are a bit like this.
Runner Table
ID|AGE|LastLap|BestLap
Laps Table
ID|Time|Date|Inserted|RunnerID
So are application had/has a bug in it that when you add a lap that was in the past from your last lap it still set the last lap id when it did not need to.
What I want to do is fix the lastlap column so that the true last lap id for each runner is the last lap id do by ordering laps table by Date for each runner but i can't figure out a SQL update script to do this. I get very close but I can't get the ID from the laps table or I get more than one result.

I'd follow Mike's statement: if it isn't some crazy performance-tuning thing, stick with a view for cases like "last..." "best...", it can minimize any hassle in this regard.
Anyways, if you "just" need to update what's broken, the following should work with MS SQL, if not great performance-wise.
Presumptions: "time" is your business-value for the lap, not time of day; "inserted" and "ID" can't be used, because someone may insert data not ordered by date.
This means: if you have more then one lap-entry per runner per day, you just have to assume that the biggest ID has your desired business-value or change your data-model.
DECLARE #RunnerID INT;
SET #RunnerID = yourRunnerID;
UPDATE RUNNERS
SET LastLap = (SELECT MAX(L.ID)
FROM Laps L
WHERE L.RunnerID = #RunnerID
AND L.DATE = (SELECT MAX(Date)
FROM Laps
WHERE Laps.RunnerID = #RunnerID
)
)
WHERE ID = #RunnerID;

Related

How to add +1 in a specific column if date in another column = '2020-11-10' for example in SQL

I'm working on a report that shows if a certain shipper performs as agreed - if they promised 1-day-delivery, it should be 1 day and not 2.
This is a screenshot of the table i created:
table
Column 'transitdays_int' shows the difference between column 'shippingdate_date' and 'deliverydate_date' in days
Column 'transit_treshold shows the number of days the shipper promised it would take to get it delivered
In column 'success_ratio' i converted these values with a CASE-statement to 'on time' or 'late delivery'
Issue i have now is that i want to add +1 to column 'transit_treshold' if column 'shippingdate_date' = '2020-11-10'. Is that even possible? I read about many different solutions, but none of them seems to be exactly what i'm looking for...
Thanks in advance!
It sounds like you just need a basic update:
UPDATE yourTable
SET transit_treshold = transit_treshold + 1
WHERE shippingdate_date = '2020-11-10'
If this is a report, you are just looking for a query and not to actually update the database values, correct?
If so, I would just update your query as:
select
case when cast(shippingdate_date as date) = cast('2020-11-10' as date)
then transit_treshold + 1
else transit_treshold
end as [Transit Days]
If you could provide your actual query it might be easier to help.
Also, what is special about 11/10/2020? Are you looking for this date to be hard coded or do you need it to be dynamic?
Update TableName
set transit_treshold=transit_treshold+1
where shippingdate_date = '20201110'

Query to select appropriate feedback record based on dates

I understand there are many questions and answers outlining how to query data with relation to dates stored in SQL. My question, while in the same vein, is not something I've been able to find a solution for.
There is a SolutionRevisions table with three relevant columns: SR_ID (primary), SR_SolutionID, and SR_CreatedDate.
There is a Feedback table with F_ID, F_ItemID (maps to SR_SolutionID) and F_CreatedDate, F_SubItemID (currently empty).
My goal is to identify which SolutionRevisions record was the active when a feedback item was created and insert the SR_ID value into F_SubItemID column. This could be done by choosing the revision record created most recently before the feedback item.
To begin, I've began by trying to select back appropriate values for testing and verification. What I have looks like this:
SELECT sr.SR_ID, f.F_ItemID, sr.SR_CreatedDateUtc, f.F_CreatedDateUtc
FROM Feedback AS f
INNER JOIN SolutionRevisions AS sr on f.F_ItemID = sr.SR_SolutionID
WHERE f.F_CreatedDateUtc > sr.SR_CreatedDateUtc
This is obviously missing a necessary portion of the where clause (thus returning inaccurate results). The where clause needs to include (in pseudo-code)
AND f.F_CreatedDateUtc < nextSRCreatedDate
^ where "nextSRCreatedDate" represents the sr.SR_CreatedDate of the next record on the SolutionRevisions table for the same SR_SolutionID. My issue lies in getting back the correct value for nextSRCreatedDate
Example data:
Any help is appreciated, if more info is requested I'll promptly reply.
Try this approach instead. It uses a subselect to determine the most recent record in the SolutionRevisions table at the time any individual Feedback record was created.
It's probably not the fastest solution (pun intended), but it should get you the desired results. If you're able to alter the subselect to a hit a better index, that would of course help with the execution time.
Update
f
Set
f.F_SubItemID = (
Select Top 1
sr.SR_ID
From
SolutionRevisions sr
Where
sr.SR_SolutionID = f.F_ItemID
And sr.SR_CreatedDateUtc < f.F_CreatedDateUtc
Order By
sr.SR_CreatedDateUtc Desc
)
From
Feedback f
My goal is to identify which SolutionRevisions record was the active when a feedback item was created and insert the SR_SolutionID value into F_SubItemID column.
I think you want outer apply:
SELECT sr.SR_ID, f.F_ItemID, sr.SR_CreatedDateUtc, f.F_CreatedDateUtc
FROM Feedback f OUTER APPLY
(SELECT sr.*
FROM SolutionRevisions sr
WHERE f.F_ItemID = sr.SR_SolutionID AND
f.F_CreatedDateUtc >= sr.SR_CreatedDateUtc
ORDER BY SR_CreatedDateUtc DESC
) sr;

Update table with combined field from other tables

I have a table with actions that are being due in the future. I have a second table that holds all the cases, including the due date of the case. And I have a third table that holds numbers.
The problems is as follows. Our system automatically populates our table with future actions. For some clients however, we need to change these dates. I wanted to create an update query for this, and have this run through our scheduler. However, I am kind of stuck at the moment.
What I have on code so far is this:
UPDATE proxima_gestion p
SET fecha = (SELECT To_char(d.f_ult_vencim + c.hrem01, 'yyyyMMdd')
FROM deuda d,
c4u_activity_dates c,
proxima_gestion p
WHERE d.codigo_cliente = c.codigo_cliente
AND p.n_expediente = d.n_expediente
AND d.saldo > 1000
AND p.tipo_gestion_id = 914
AND p.codigo_oficina = 33
AND d.f_ult_vencim > sysdate)
WHERE EXISTS (SELECT *
FROM proxima_gestion p,
deuda d
WHERE p.n_expediente = d.n_expediente
AND d.saldo > 1000
AND p.tipo_gestion_id = 914
AND p.codigo_oficina = 33
AND d.f_ult_vencim > sysdate)
The field fecha is the current action date. Unfortunately, this is saved as a char instead of date. That is why I need to convert the date back to a char. F_ult_vencim is the due date, and hrem01 is the number of days the actions should be placed away from the due date. (for example, this could be 10, making the new date 10 days after the due date)
Apart from that, there are a few more criteria when we need to change the date (certain creditors, certain departments, only for future cases and starting from a certain amount, only for a certain action type.)
However, when I try and run this query, I get the error message
ORA-01427: single-row subquery returns more than one row
If I run both subqueries seperately, I get 2 results from both. What I am trying to accomplish, is that it connects these 2 queries, and updates the field to the new value. This value will be different for every case, as every due date will be different.
Is this even possible? And if so, how?
You're getting the error because the first SELECT is returning more than one row for each row in the table being updated.
The first thing I see is that the alias for the table in UPDATE is the same as the alias in both SELECTs (p). So all of the references to p in the subqueries are referencing proxima_gestion in the subquery rather than the outer query. That is, the subquery is not dependent on the outer query, which is required for an UPDATE.
Try removing "proxima_gestion p" from FROM in both subqueries. The references to p, then, will be to the outer UPDATE query.

How Do I Get Total 1 Time for Multiple Rows

I've been asked to modify a report (which unfortunately was written horribly!! not by me!) to include a count of days. Please note the "Days" is not calculated using "StartDate" & "EndDate" below. The problem is, there are multiple rows per record (users want to see the detail for start & enddate), so my total for "Days" are counting for each row. How can I get the total 1 time without the total in column repeating?
This is what the data looks like right now:
ID Description startdate enddate Days
REA145681 Emergency 11/17/2011 11/19/2011 49
REA145681 Emergency 12/6/2011 12/9/2011 49
REA145681 Emergency 12/10/2011 12/14/2011 49
REA146425 Emergency 11/23/2011 12/8/2011 54
REA146425 Emergency 12/9/2011 12/12/2011 54
I need this:
ID Description startdate enddate Days
REA145681 Emergency 11/17/2011 11/19/2011 49
REA145681 Emergency 12/6/2011 12/9/2011
REA145681 Emergency 12/10/2011 12/14/2011
REA146425 Emergency 11/23/2011 12/8/2011 54
REA146425 Emergency 12/9/2011 12/12/2011
Help please. This is how the users want to see the data.
Thanks in advance!
Liz
--- Here is the query simplified:
select id
,description
,startdate -- users want to see all start dates and enddates
,enddate
,days = datediff(d,Isnull(actualstardate,anticipatedstartdate) ,actualenddate)
from table
As you didn't provide the data of your tables I'll operate over your result as if it was a table. This will result in what you're looking for:
select *,
case row_number() over (partition by id order by id)
when 1 then days
end
from t
Edit:
Looks like you DID added some SQL code. This should be what you're looking for:
select *,
case row_number() over (partition by id order by id)
when 1 then
datediff(d,Isnull(actualstardate,anticipatedstartdate) ,actualenddate)
end
from t
That is a task for the reporting tool. You will have to write something like he next code in teh Display Properties of the Days field:
if RowNumber > 1 AND id = previous_row(id)
then -- hide the value of Days
Colour = BackgroundColour
Days = NULL
Days = ' '
Display = false
... (anything that works)
So they want the output to be exactly the same except that they don't want to see the days listed multiple times for each ID value? And they're quite happy to see the ID and Description repeatedly but the Days value annoys them?
That's not really an SQL question. SQL is about which rows, columns and derived values are supposed to be presented in what order and that part seems to be working fine.
Suppressing the redundant occurrences of the Days value is more a matter of using the right tool. I'm not up on the current tools but the last time I was, QMF was very good for this kind of thing. If a column was the basis for a control break, you could, in effect, select an option for that column that told it not to repeat the value of the control break repeatedly. That way, you could keep it from repeating ID, Description AND Days if that's what you wanted. But I don't know if people are still using QMF and I have no idea if you are. And unless the price has come way down, you don't want to go out and buy QMF just to suppress those redundant values.
Other tools might do the same kind of thing but I can't tell you which ones. Perhaps the tool you are using to do your reporting - Crystal Reports or whatever - has that feature. Or not. I think it was called Outlining in QMF but it may have a different name in your tool.
Now, if this report is being generated by an application program, that is a different kettle of Fish. An application could handle that quite nicely. But most people use end-user reporting tools to do this kind of thing to avoid the greater cost involved in writing programs.
We might be able to help further if you specify what tool you are using to generate this report.

How can I Insert or Update a row with a value returned from a sub-query?

EDIT: Looking for help from J. Leffler, Cheese Con Queso or anyone who knows Informix-SE well.
Informix-SE 4.11:
I have a table called 'cuadre' which is used to reconcile the cash drawer at the end of each business day (Monday thru Saturday). Once the drawer has been reconciled, the amount in the cash drawer is stored in column 'cu_sa_cash', the row is saved and the system is shutdowned, the store is closed for the day and we all go have some beers.. On the next business day, we start up the system, run an SQL procedure that creates (inserts) a new row in the cuadre table for that days postings and repeat the cycle again.
I would like for my SQL proc to INSERT the new row for the current day with the same cash in drawer amount that was stored in the previous business days row. Keep in mind that this is not SPL, as I'm still using SE 4.11.. So, the below SQL statements are the general idea of what I want to accomplish, but they don't work!.. Can you provide me with solution?.. Thanks!
INSERT INTO cuadre(cu_date,cu_en_dincaja)
VALUES (TODAY,(SELECT cu_sa_cash
FROM cuadre
WHERE cu_date = (SELECT MAX(cu_date)
FROM cuadre)));
or
INSERT INTO cuadre(cu_date)
VALUES(TODAY);
UPDATE cuadre
SET cu_en_dincaja = (SELECT cu_sa_cash
FROM cuadre
WHERE cu_date = TODAY - 1)
WHERE cu_date = TODAY;
I know nothing about informix in particular, but this is an alternative syntax...
INSERT INTO
cuadre (
cu_date,
cu_en_dincaja
)
SELECT
TODAY,
cu_sa_cash
FROM
cuadre
WHERE
cu_date = (SELECT * FROM (SELECT MAX(cu_date) FROM cuadre))
;
NOTE: This may return multiple rows if cu_date is not unique.
EDIT Added MySQL work around for reading from and writing to the same table. Worth a test in Informix?
using a temp table was the solution to the problem