How can I make selection based on conditions on SQL? - sql

There is a table based on ID an those ID's status keys:
The table
I need to write query that will bring higher status key of the same ID. For example; query will bring only the row with status key number 9 for ID number 123. But it will bring the row with status key number 2 for ID number 156.
Hope I managed to explain myself clearly. Please help me with this query.

Use max() aggregation
select id, max(status_key)
from tablename
group by id

You didn't tag your backend, this would work with many backends and older versions of many backends (assuming you have other columns too in your table - otherwise do only group by):
select myTable.*
from myTable
inner join
(select id, max(statusKey) as statusKey
from myTable
group by id) tmp on myTable.id = tmp.id and myTable.statusKey = tmp.statusKey;

Related

SQL query to combine Select duplicates with count and grouping with delete based on Top but not the top 1 of each duplicate

I am looking to combine these 2 statement into one to run as a stored procedure if possible.
I have not used temp tables in queries before and may have to with this, not sure asking advice.
I did not write the original queries and manually run the first one which returns a table listing ID's with duplicate data nad how many records. Then each record ID is put into the 2nd query to remove all but the TOP 1 based on additional filtering criteria.
I have looked at using CTE from SQL select into delete DIRECTLY but am stil at a loss on how to pass each result row ID value into the delete query.
The queries, edited for public consumption are
SELECT id, count() FROM [DEV].[dbo].[7dtest] where FileVer = 1 and CALC_DATE > FORMAT(DATEADD(DD,-7,GETDATE()), 'yyyy-MM-dd') group by id having count() > 1 order by count(*) desc
returns a table with id and number of duplicate rows
then take the id of each row and put into this delete statement
delete from [DEV].[dbo].[7dtest] where AutoID not in (
SELECT TOP 1 AutoID FROM [DEV].[dbo].[7dtest] where FileVer = 1 and id = '123' and CALC_DATE > FORMAT(DATEADD(DD,-7,GETDATE()), 'yyyy-MM-dd')
order by COMPLETED_DATE_CHECK_3 desc, COMPLETED_DATE_CHECK_2 desc, COMPLETED_DATE_CHECK_1 desc)
and FileVer = 1 and id = '123' and CALC_DATE > FORMAT(DATEADD(DD,-7,GETDATE()), 'yyyy-MM-dd')
Can this be done with CTE or do I need to create a temp table and some looping to get the ID one row at a time? Is there a better way I should be doing this?
TIA

Optimized query to get the most recent records for each person in a log table

Is there a better way to setup this query?
select *
from peopleLog
where index in (select max(index) index from peopleLog group by personID)
I have a log table that is inserted into every time a person's record is updated. The records are added, not replaced. This means that the table contains multiple records for each person. I want to pull the most resent record for each person from this table. The table has about 30 fields, so I don't think that grouping would be the best option, but I might be wrong.
The index field is the identity field in this SQL Server table, and is set to auto increment.
personID is the person's identification number and is unique the person.
you can use window function instead:
select * from (
select * , row_number() over (partition by personID order by index desc) rn
from peopleLog
) t where t.rn = 1
also an index on personId and "index" column would help)
Often a correlated subquery has the best performance:
select pl.*
from peopleLog pl
where pl.index = (select max(pl2.index)
from peopleLog pl2
where pl2.personID = pl.personID
);
In particular, this can take advantage of an index on peopleLog(personID, index).

returning the full row of a grouped by query

I have a query that essentially tries to get the max serial value for each distinct other_field (simplified example below).
there are a few fields you need to know about
ID text
ser serial
other_field text
For each distinct other_field I want to find the full row with the largest serial value
I basically want to return the whole row but end up having to join on the same table to retrieve what I want (since the group by clause is generally so restrictive). The query I use below
SELECT small_q.id FROM (
SELECT id, MAX(ser) as serial FROM table_name GROUP BY other_field
) max_q JOIN table_name full_t ON small_q.serial = max_q.serial
Is there any way for me to avoid having to join on the same table?
Many thanks in advance
The easy answer would be to use windowing function:
SELECT main.* FROM (
SELECT *, MAX(ser) over (partition by other_field) as serial FROM table_name
) main where main.ser=main.serial
If you are looking for only one row per other_field, I strongly advocate distinct on in Postgres:
SELECT DISTINCT ON (other_field) t.id
FROM table_name t
ORDER BY other_field, ser DESC ;
In Postgres, DISTINCT ON usually has better performance characteristics than other ways of accomplishing the same thing.

Retrieve records from a table which has different partial key

I have a table like as follows:
Table 1 Schema
ID/Name/Description are part of primary key.
Table Structure with data
Now, I want to compare table records on the basis of ID and need to find records which are not matching. for e.g. from above screen print I want last row as my query result.
I will be really thankful for any input. Thanks !
select t1.*
from
table t1
join
(
select name,description,comment
from
table t2
group by
name,description,comment
having count(*)=1) b
on t1.name=b.name
and t1.description=b.description
and t1.comment=b.comment
If using SQLServer,this does the trick..
SELECT TOP 1 WITH TIES ID,NAME,DESCRIPTION,COMMENT
FROM
#TEMP
ORDER BY
COUNT(ID) OVER (PARTITION BY NAME,DESCRIPTION,COMMENT )

SQL - Group By unique column combination

I am trying to write a script that will return the latest values for a unique documentid-physician-patient triplet. I need the script to act similar to a group by statement, except group by only works with one column at a time. I need to date and status information for only the most recent unique triplet. Please let me know what you will need to see from me to help. Here is the current, very bare, statement:
SELECT
TransmissionSend.CreateTimestamp,
TransmissionSendItem.Status,
TransmissionSendItem.PhysicianId,
TransmissionSendItem.DocumentIdDisplay,
Utility.SqlFunctions_NdnListToAccountList(TransmissionSendItem.NdocNum) AS AccountNum
FROM
Interface_SFAX.TransmissionSend,
Interface_SFAX.TransmissionSendItem
WHERE
TransmissionSend.ID = TransmissionSendItem.childsub --I don't know exactly what this does, I did not write this script. It must stay here though for the exact results.
ORDER BY TransmissionSend.CreateTimestamp DESC -- In the end, each latest result of the unique triplet will be ordered from most recent to oldest in return
My question is, again, how can I limit results to only the latest status for each physician id, document id, and account number combination?
First select the MAX(date) with the documentid GROUP BY documentid then select all data from the table by the first select result for example with an inner join.
SELECT table.additionalData, J.id, J.date
FROM table
INNER JOIN (SELECT id, MAX(date) AS date
FROM table GROUP BY id) AS J
ON J.id = table.id
AND J.date /* this is the max date */ = table.date