How to get MIN of a column based of another column without sub query? - select

I want to get the min(id) from a table based on the date inserted, as not always the min(id) will be the same as the id of the min(date_inserted). I can do it with subquery but I need to do it without the subquery as it is part of a bigger SQL.
This is what I got so far:
create table tbl(
id int ,
userid int,
dt timestamp)
SELECT id
FROM (
-- if I could do min(id order by dt) that would solve the issue
select id, row_number() over(partition by userid order by dt) row_number
from table
where userid = :userid
) withs
WHERE row_number=1

Related

How to order by result set in union query in T-SQL

I want to use order by clause in my last sql query and I have more than 3 union queries. I do not want to order the top 2 union query but I want to use order by clause in my last sql statement.
Currently, getting error
ORDER BY items must appear in the select list if the statement contains a UNION, INTERSECT or EXCEPT operator.
select 'Total Number of pat' Name, convert(varchar(20), count(id)) Number from table2 where id = 5
union
select 'Total Number of Doc' Name, convert(varchar(20), count(id)) Number from table3
union
select x.usertype, count(distinct userid) cnt
from [dbo].table1 t
cross apply (values (
case when t.userid like '%[0-9][0-9[0-9]' then 'transition' else 'non transition' end,
t.userid
)) x(usertype, userid)
where t.date >= dateadd(day,-7, getdate())
group by x.usertype
order by usertype desc
order by is sorting the result of the unions all together however you can introduce a orderIndex column for imlementing the right ordering.
Here the sample:
I've tried to build sample data in the following code.
create table table1(
userid varchar(100),
usertype varchar(100),
date date
)
insert into table1(userid, date) values ('Einsmayr', '2020-10-27')
insert into table1(userid, date) values ('Eins123', '2020-10-27')
insert into table1(userid, date) values ('Einschmid', '2020-10-27')
insert into table1(userid, date) values ('Einshuber', '2020-10-27')
insert into table1(userid, date) values ('Einsreitmayr', '2020-10-27')
create table table2 (
Name varchar(100),
id int
)
insert into table2(Name, id) values('Zweirich', 5)
insert into table2(Name, id) values('Zweifel', 6)
create table table3 (
Name varchar(100),
id int
)
insert into table3(Name, id) values('Dreisinger', 17)
insert into table3(Name, id) values('Dreibert', 18)
This allows the following queries:
select usertype, Number
from (
select 'Total Number of pat' usertype, convert(varchar(20), count(id)) Number, 1 orderIndex from table2 where id = 5
union
select 'Total Number of Doc' Name, convert(varchar(20), count(id)) Number, 2 orderIndex from table3
union
select usertype, count(distinct userid) Number, 3 orderIndex
from (
select userid, case when userid like '%[0-9][0-9[0-9]' then 'transition' else 'non transition' end usertype
from table1
where date >= dateadd(day,-7, getdate())
) x
group by x.usertype
) y
order by y.orderIndex, y.usertype
Find the solution here: https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=ac396c48f5dbcb4a53ad40fac70e9236

I want to delete duplicate rows from a MySQL table. Please click on the below link to see the table data

I tried to do it with this query, but it's not working...
DELETE FROM employee
WHERE ( SELECT * FROM
(SELECT row_number() OVER (partition by id) rn FROM employee) alias
) > 1;
Please click on this link to view the table
The above query is not working and giving this error message:
Error Code: 1242. Subquery returns more than 1 row
try like below by using subquery
delete from
(
select *.row_number() over (partition by id order by id) rn
from employee
) alias where rn > 1;
You are matching an integer (1) with set of rows returned from the subquery, which SQL will not allow
You can match an integer (1) with a single value returned from the subquery.
Use below query (using CTE) to remove duplicates.
;WITH TempEmp (id,duplicateRecCount)
AS
(
SELECT id,ROW_NUMBER() OVER(PARTITION by id ORDER BY id)
AS duplicateRecCount
FROM employee
)
DELETE FROM TempEmp
WHERE duplicateRecCount > 1

Find rank in SQL table

I have a test table
ID V_ID
1 1
1 2
I want max(V_ID) and resulr should be V_ID 2
select Id,max(V_ID) from test
group by Id,value
I am trying simple query but it's still pulling two records. Is there any other simple query 1) we can try rank 2)?
You should be grouping only by the ID column:
SELECT ID, MAX(V_ID)
FROM test
GROUP BY IdD;
A more general pattern for this type of problem uses ROW_NUMBER to find the entire record for each Id having the max value of V_ID:
SELECT ID, V_ID
FROM
(
SELECT *, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY V_ID DESC) rn
FROM test
) t
WHERE rn = 1;

Get second last row for every record in postgresql query

I had table lets say table_inventory. On the table_inventory i put a trigger for every update of stock insert new row in audit_inventory table:
table column are look like:
table_inventory
|sr_id|inventory_id|p_name|stock|
audit_inventory
|insert_time||sr_id|inventory_id|p_name|stock|
Now my problem is for every inventory_id of table_inventory there are multiple entry in audit_inventory as i put trigger for every update of stock insert a row with time in audit_inventory, so i want to select second last stock value for every inventory_id of table_inventory. I write some cte to do that but unable to get for every inventory_id.
WITH CTE as
(select inventory_id,stock from table_inventory),
cte_1 as(
SELECT
stock,
row_number() over (order by insert_time desc) rn
FROM audit_inventory where inventoryid in (select inventory_id from cte)
),cte_2 as(
SELECT stock
FROM CTE
WHERE rn = 2)
select * from cte,cte_1;
The above query retrns the second last value for single inventory_id but did not understand how to write query for getting second last row value for every inventory_id of table_inventory.
Thanks for your precious time.
Try doing this. I guess this is what you want:
WITH CTE as
( SELECT
stock,
inventory_id,
row_number() over (PARTITION BY inventoryid order by insert_time desc) rn
FROM audit.inventory
)
SELECT
CTE.stock,
ti.inventory_id,
ti.stock
FROM
table_inventory ti
inner join CTE on CTE.inventory_id=ti.inventory_id
WHERE
CTE.rn=2

Update same table by its maximum date

I have a table in which i have to find the maximum date for each unique EMPid & testid
below is the input table and expected output
I tried with correlated sub query but that didn't work.
Any quick way to update the table with max date.
You can use a common-table-expression and the OVER clause with PARTITION BY:
WITH CTE AS
(
SELECT EmpId, [Hall Id], testId, Date, [Max date],
MaxDate = MAX(Date) OVER (PARTITION BY EmpId, testId)
FROM dbo.TableName
)
UPDATE CTE SET [Max date] = MaxDate
If you want to see what will happen replace UPDATE with SELECT * FROM.
You can use a CTE to select all maximum dates and join this with your original data like this:
WITH MaxDates AS (
SELECT empid
, testid
, MAX(Date) AS MaxDate
FROM table
GROUP BY empid
, testid
)
SELECT table.*
, MaxDate
FROM table
INNER JOIN MaxDates ON table.empid = MaxDates.empid AND table.testid = MaxDates.testid