SQL- Need to Order By date first and then have a specific variable value always come first - sql

I need to order by results to order by date first but then to have a specific variable value (trackingbasisID=4) to always be ordered first. Below is an example. I have many variables in the select statement.I've also attached the graph of how results are shown. We'd liked to avoid the W in the graph s so we want the delay (TrackingBasisID=4) to always display first over all other id's but still sort by date first. My Current OrderBy Statement is simply:
ORDER BY hd.Date ASC, hd.PreimPhaseNumber ASC
There are trackingbasis ID of 1,2,3,4,5,6 -- Of which We always want 4 to come first when being ordered.

Related

Returning Only Latest Result For Location in SQL [duplicate]

This question already has answers here:
How do I limit the number of rows returned by an Oracle query after ordering?
(14 answers)
Closed last year.
I'm wanting to find the very last pallet placed in a given batch of locations within a warehouse.
I currently have:
SELECT
max(datreg) AS "_Reg Date",
logguser,
mha,
rack,
horcoor,
vercoor
FROM
L16T3
WHERE
l16lcode = '3'
AND
rack = #('Rack?',rack)
AND
horcoor >= #('Loc From?',horcoor)
AND
horcoor <= #('Loc To?',horcoor)
ORDER BY 1
LIMIT 1
I thought this would return just the last pallet placed in that specific location, but I'm still getting like 4 entries for one location.
I would only want the highlighted result, as that is the most recent pallet placed in 110-001-04:
I'm sure this is super simple but im just starting out :)
You can use a combination of ORDER BY and LIMIT to achieve what you want.
Limit
In a lot of other databases, this is called LIMIT, but I missed that you are using an Oracle database, which has a different dialect of SQL. In Oracle, the most direct equivilent of a limit is:
FETCH FIRST n ROWS ONLY
This means that your query can return at most n rows. So, for example, FETCH FIRST 1 ROWS ONLY means that it can return at most 1 row. The issue is that it takes rows from the start of the table, not the end (and despite the wording implying FETCH LAST n ROWS ONLY would be a thing, it doesn't seem to be) --- you can essentially think of it as cutting off the rows below given limit.
For example, if I have rows in order "A", "B", and "C", FETCH FIRST 1 ROWS ONLY only returns "A". If "C" was really the one I wanted (e.g. the row at the bottom), then I would need to add an ORDER BY clause to first order the results so that the one I want is at the top.
Order By
ORDER BY column dir orders your results by a specific column in a specific direction, e.g. in ascending (ASC) or descending (DESC) order. The syntax actually allows for more complex ordering (e.g. ordering by multiple columns or by a function), but for this simple case this should do what we need.
Putting it together
You want to order so that your desired row is at the top of your table, then you want to limit your results set to contain at most one row.
Adding something like this to the end of your query should work:
ORDER BY "_Reg Date" DESC
FETCH FIRST 1 ROWS ONLY

How to determine the order of the result from my postgres query?

I have the following query:
SELECT
time as "time",
case
when tag = 'KEB1.DB_BP.01.STATUS.SOC' THEN 'SOC'
when tag = 'KEB1.DB_BP.01.STATUS.SOH' THEN 'SOH'
end as "tag",
value as "value"
FROM metrics
WHERE
("time" BETWEEN '2021-07-02T10:39:47.266Z' AND '2021-07-09T10:39:47.266Z') AND
(container = '1234') AND
(tag = 'KEB1.DB_BP.01.STATUS.SOC' OR tag = 'KEB1.DB_BP.01.STATUS.SOH')
GROUP BY 1, 2, 3
ORDER BY time desc
LIMIT 2
This is giving me the result:
Sometimes the order changes of the result changes from SOH -> SOC or from SOC -> SOH. I'm trying to modify my query so I always get SOH first and than SOC.. How can I achieve this?
You have two times that are identical. The order by is only using time as a key. When the key values are identical, the resulting order for those keys is arbitrary and indeterminate. In can change from one execution to the next.
To prevent this, add an additional column to the order by so each row is unique. In this case that would seem to be tag:
order by "time", tag
You want to show the two most recent rows. In your example these have the same date/time but they can probably also differ. In order to find the two most recent rows you had to apply an ORDER BY clause.
You want to show the two rows in another order, however, so you must place an additional ORDER BY in your query. This is done by selecting from your query result (i.e. putting your query into a subquery):
select *
from ( <your query here> ) myquery
order by tag desc;
Try this:
order by 1 desc, 2
(order by first column descending and by the second column)

Return Files w/o Note in at least X Days

We have a customer database and I'm trying to get all of the customer files that haven't had a comment on them in three weeks or more.
I'm working with two tables; the file table with info about the file like which staff is assigned to it, and the comments table, where all the comments in the database are. They're linked by the file number field.
If I wanted the file number and date of last note, what SQL should I be using?
I have tried:
SELECT db_file_notes.file_num, Last(db_file_notes.file_date) AS
LastOfnote_date, Last(db_file_notes.note_key) AS LastOfnote_key
FROM db_file_notes
GROUP BY db_file_notes.file_num
ORDER BY db_file_notes.file_num, Last(db_file_notes.note_date);
There are a handful of files that are on the resulting query that shouldn't be. For example, file # 212720's last note was on 7/28, but the above query returns a last note date of 6/26 (the previous last note). Then there's file # 212781 with actual last note on 7/21, but the query is return 6/12 (there five newer notes since the one returned by the query).
There's no date criteria in the above SQL but if I add the <=Date()-21 it's still incorrect (212710 is still there with a last note of 6/26). Interestingly, if I add a filter on the file number to only return a single file number like 212720, the last note date returns correctly.
I've tried sorting by file number then note date, and file number and note key (on the general assumption that newer notes have higher key values) and get the same behavior. Instead of sorting ascending then taking the last record, I've tried sorting descending and taking the first; this returns the correct note for the files affected by the above, but then new cases have the problem but in reverse now.
Sample table:
Without bringing in the second table you could use either of these:
This will return the top grouped date. For example, if your maximum file_date is 12/06/2017 this will return all the records that have a file_date of 12/06/2017.
SELECT TOP 1 file_num
, file_date
, note_key
FROM db_file_notes
WHERE DATEDIFF("d",file_date,DATE())>=21
ORDER BY file_date DESC
This code, on the other hand, will return the maximum date for each group of figures (a group being sets of file_num and note_key)
SELECT file_num
, MAX(file_date) AS Max_File_date
, note_key
FROM db_file_notes
WHERE DATEDIFF("d",file_date,DATE())>=21
GROUP BY file_num, note_key
Note: You don't have to qualify each field name with the table name if the field is unique across all tables (or you're just using one table).

Access VBA: Get difference in value between current and previous record

I have made report based on query according to this link:
http://www.techonthenet.com/access/queries/max_query2.php
It gives me list of records with values:
(primaryKey)
ID.......FirstNum....SecNum.....Diameter.....Owner
1........100200.......01...............150..............Peter
2........100200.......02...............138..............Peter
3........100300.......07...............112..............John
Query sorts records in descending order by Diametral. I want make new column which will count difference between first and second record, then between third and second and so on. Like this:
(primaryKey)
ID.......FirstNum....SecNum.....Diameter.....DiffDiametral.....Owner
1........100200.......01...............150.......................................Peter
2........100200.......02...............138.............12......................Peter
3........100300.......07...............112.............26.....................John
What should I write into RowSource or DataSource for DiffDiametral to get these values? How can I avoid error for first line, where is not previous value which I want substract from?
I tried to solve it according to this link:
http://support.microsoft.com/kb/101081/en-us
but I did not solve it. Simply I dont know how I can refer previous value of Diameter to count difference.
Based on your information, a subquery should do it. Just substitute your actual table name for tblDiameters.
SELECT C.ID, C.FirstNum, C.SecNum, C.Diameter, C.Owner,
(SELECT TOP 1 P.Diameter
FROM tblDiameters AS P
WHERE P.Diameter < C.Diameter
ORDER BY P.Diameter DESC )
- C.Diameter AS DiffDiameter
FROM tblDiameters AS C

"Totals" Query: show last non-blank string

I have a totals query (one where I clicked the totals button, and it has "group by" columns) in Access 2007. Most of the columns are fine... group by columns, max columns, min columns, etc. For some of them though, I want to extract only the last non-blank (not "" or null) value of a string column.
Here's a sample of what my SQL looks like:
SELECT Min(Duplicates.AttendedODBefore) AS AttendedODBefore,
Min(Duplicates.ContactByPost) As ContactByPost,
Last(Duplicates.PlannedStart) As PlannedStart,
Min(Duplicates.AccessibilityRequirements) AS AccessibilityRequirements,
Last(Duplicates.UcasNumber) As UcasNumber
-- ^^^^
FROM DuplicateStudents As Duplicates
GROUP BY
Duplicates.ID
The expression highlighted is the one I want changing to the last non-blank field. Is there an Access-specific or plain SQL expression which will do this?
Edit: Turns out that Min() and Max() work on string values and ignores null values, taking the first and last values alphabetically. It's not perfect, because it doesn't guarantee that the value selected is the last one, but it's better than just a load of nulls which is what using Last() might give.
Access seems resistant to the idea of returning the last non-null value in a query using GROUP BY. Even if your FROM clause were modified to be something like
FROM (
SELECT allfieldsyouneed
FROM DuplicateStudents
ORDER BY PlannedStart
) AS SortedDuplicates
and the rest of your query were modified to use SortedDuplicates instead, Access doesn't seem to return the last value based on the order you specify. I tested on a table with exactly one blank row and specific orders that I could verify (both an auto-increment field and a value that I checked by using Min and Max), and Access chose to return some other value as Last.
Based on your comment it seems like your definition of "Last" is: the most recently added record, based on an auto-incrementing ID. As such, some form of the following should work (it uses a subquery to return the most recent non-null UcasNumber):
SELECT Min(Duplicates.AttendedODBefore) AS AttendedODBefore,
Min(Duplicates.ContactByPost) As ContactByPost,
Last(Duplicates.PlannedStart) As PlannedStart,
Min(Duplicates.AccessibilityRequirements) AS AccessibilityRequirements,
(SELECT TOP 1 D.UcasNumber FROM Duplicates AS D
WHERE D.UcasNumber Is Not Null
ORDER BY D.ID DESC) As UcasNumber
FROM DuplicateStudents As Duplicates