SQL Selecting Maximum Based on Minor-Major scheme - tsql

I am trying to create a query that will select a DISTINCT line, select using a revision Minor / Major scheme. Below is an example table:
Serial Number | RevMajor | RevMinor
-----------------------------------
AQ155 | 1 | 1
AQ155 | 1 | 2
AQ155 | 1 | 1
AQ155 | 1 | 7
AQ155 | 2 | 1 <---------
JR2709 | 1 | 7
JR2709 | 2 | 2 <---------
How can I write a query in T-SQL 2008 that will select only the two highlighted lines, the "Newest Revision"?
Thanks in advance!

You could
select * from (
select *, row_number() over (partition by [Serial Number] order by RevMajor desc, RevMinor desc) VersionRank
from table
) T
where VersionRank = 1

select [serial number], revmajor, revminor
from table1
where revMajor = (select max(revmajor) from table1)
another way to do this could be:
select [serial number], revmajor, revminor
from table1 a
inner join ( select max(revMajor) from table1 ) b on a.revmajor = b.revmajor
Another way if you know there are only 2 rows:
select top 2 [serial number], revmajor, revminor
from table1 a
order by revmajor desc, revminor desc

Related

Inner join and update the table in one execution DB2

I have two tables, where I would like to update table_2 if the column's value is same and then applying inner join with table1. I would like to do in one execution.
Here I habe table1 and table2, where item_2 of table2 has same value with status = 0. Here I would like to update one of the status with 9.
table1
#|ID| ITEM_1 |Application
-+--+----------+------
1|1| item1 | read
2|2| item1 | write
3|3| item1 | learn
table2
#|ID| ITEM_2 |Description |STATUS
-+--+---------+---------------------
1|10| item1 | des1 | 0
2|11| item1 | des2 | 0
3|12| item1 | des3 | 2
For updating table2, I used lag() function and then inner join with table1.
But here I need to execute two times, first for update and then second for inner join. But I am looking to execute in one time.
update
UPDATE
(
SELECT
T2.*
, lag(ITEM_2, 1, 0) over (order by ITEM_2 ASC) as C2
FROM TABLE_2 T2 where T2.STATUS = 0
)
SET STATUS = 9
WHERE C2 = ITEM_2;
#|ID| ITEM_2 |Description |STATUS
-+--+---------+---------------------
1|10| item1 | des1 | 0
2|11| item1 | des2 | 9
3|12| item1 | des3 | 2
inner join
select T1.ID, T1.ITEM_1, T1.Appliction, T2.ID, T2.ITEM_2, T2.Description, T2.STATUS
from TABLE_1 T1
INNER JOIN TABLE_2 T2 ON T1.ITEM_1 = T2.ITEM_2
where T2.STATUS = 0
ID | ITEM_1 | APPLICTION | ID | ITEM_2 | DESCRIPTION | STATUS
1 | item1 | read | 10 | item1 | des1 | 0
WITH U AS
(SELECT COUNT (1) AS DUMMY FROM NEW TABLE
(UPDATE TABLE_2 A SET STATUS = 9 WHERE EXISTS
(SELECT 1 FROM TABLE_2 B WHERE A.ITEM_2 = B.ITEM_2 AND A.ID > B.ID AND B.STATUS = 0
)))
select T1.ID, T1.ITEM_1, T1.Appliction, T2.ID, T2.ITEM_2, T2.Description, T2.STATUS
from TABLE_1 T1
Inner join TABLE_2 T2 ON T1.ITEM_1 = T2.ITEM_2
where T2.STATUS = 0`
fiddle

RECURSIVE query for Postgres on a single table

I want to create one RECURSIVE query on a single table in Postgres, which is basically base on Parent and child.
Here is the demo table employee with data
id parentid managerid status
------------------------------------
3741 [null] 1709 7
3742 3741 1709 12
3749 3742 1709 12
3900 3749 1709 4
1) If Status = 12 then the result will be, the data which has status = 12 and all the parents of that particular node.
The expected result will be :
id parentid managerid status
--------------------------------------
3741 [null] 1709 7
3742 3741 1709 12
3749 3742 1709 12
For that I have tried the query which is given below is working fine and giving proper result, even if I change the status value than also its working fine.
WITH RECURSIVE nodes AS (
SELECT s1.id, case when s1.parentid=s1.id then null else s1.parentid end parentid,s1.managerid, s1.status
FROM employees s1 WHERE id IN
(SELECT employees.id FROM employees WHERE
"employees"."status" = 12 AND "employees"."managerid" = 1709)
UNION ALL
SELECT s2.id, case when s2.parentid=s2.id then null else s2.parentid end parentid,s2.managerid, s2.status
FROM employees s2 JOIN nodes ON s2.id = nodes.parentid
)
SELECT distinct nodes.id, nodes.parentid, nodes.managerid, nodes.status
FROM nodes ORDER BY nodes.id ASC NULLS FIRST;
2) If Status != 12 then the result will be, only all the parents of that particular node.
The expected result will be :
id parentid managerid status
--------------------------------------
3741 [null] 1709 7
I want the query for status not equal some value.
WITH RECURSIVE cte AS (
SELECT * FROM tablename
WHERE status != 12
UNION
SELECT t.*
FROM tablename t INNER JOIN cte c
ON c.parentid = t.id
)
SELECT DISTINCT * FROM cte;
For more refer the Demo: demo
This is a very simple solution but I think it should work for smaller sets of data
SELECT * FROM employee
WHERE
status=12
OR id IN (
SELECT DISTINCT parentId FROM employee WHERE status=12
)
`
With this recursive CTE:
with recursive cte as (
select * from tablename
where status = 12
union all
select t.*
from tablename t inner join cte c
on c.parentid = t.id
)
select distinct * from cte;
See the demo.
Results:
| id | parentid | managerid | status |
| ---- | -------- | --------- | ------ |
| 3741 | | 1709 | 7 |
| 3742 | 3741 | 1709 | 12 |
| 3749 | 3742 | 1709 | 12 |
WITH RECURSIVE CTE AS
(
SELECT *
FROM tablename
WHERE status = 12
UNION
SELECT t.*
FROM tablename t
INNER JOIN cte c ON c.Id = t.parentid
)
SELECT t.*
FROM tablename t
LEFT JOIN cte c on t.id=c.id
WHERE c.id IS NULL
ORDER BY id ASC NULLS FIRST;

How to data show Data Row Column in Postgresql?

Here is my data and query. I want row data show in columns... Can someone help me to modify the query? I am using PostgreSQL queries.
select
ss.name, ip.product_name, ssr.quantity
from
services_servicerecipe ssr
inner join
services_service ss on ssr.service_id = ss.id
inner join
inventory_product ip on ssr.product_id = ip.id
order by
ss.name
Output:
Service_name | Product_name | Quantity
-------------+------------------+-----------
Balayage | 7.3-revlon | 2
Balayage | 701-revlon | 1
I want it to look like this
Service_name | Product_name | Quantity | Product_name | Quantity
-------------+-------------------+--------------+------------------+----------
Balayage | 7.3-revlon | 2 | 701-revlon | 1
Here is a pivot option, using ROW_NUMBER:
with cte as (
select ss.name, ip.product_name, ssr.quantity,
row_number() over (partition by ss.name order by ip.product_name) rn
from services_servicerecipe ssr
inner join services_service ss on ssr.service_id = ss.id
inner join inventory_product ip on ssr.product_id = ip.id
)
select
name,
max(case when rn = 1 then product_name end) as product1,
max(case when rn = 1 then quantity end) as quantity1,
max(case when rn = 2 then product_name end) as product2,
max(case when rn = 2 then quantity end) as quantity2
from cte
group by name;

How to count rows in SQL Server with range distinct to count the record within range

SELECT Distinct
m_KioskInformationHdr.kioskID,m_KioskInformationHdr.agency,
m_KioskInformationHdr.kioskIP,
COUNT(distinct m_KioskInformationHdr.KioskID) as NoDT
from
m_KioskInformationHdr
inner join
t_KioskStatus ON t_kioskStatus.kioskID = m_KioskInformationHdr.kioskID
where
t_KioskStatus.IsOpen = 1
and DatePost between '2014-01-20 00:00:00' and '2014-01-21 23:59:59'
group by
t_KioskStatus.DatePost, m_KioskInformationHdr.kioskID,
m_KioskInformationHdr.kioskIP, m_KioskInformationHdr.agency
I want this output:
01254878 | PHilippines,Pasig | 192.168.2.8 | 2
This is my current output:
01254878 | PHilippines,Pasig | 192.168.2.8 | 1
01254878 | PHilippines,Pasig | 192.168.2.8 | 1
How can I do this query?
Select
mk.kioskID, mk.agency, mk.kioskIP, count(mk.kioskID) as NoDT
from
(
SELECT
m_KioskInformationHdr.kioskID,m_KioskInformationHdr.agency,m_KioskInformationHdr.kioskIP
from
m_KioskInformationHdr
inner join
t_KioskStatus ON t_kioskStatus.kioskID = m_KioskInformationHdr.kioskID
where
t_KioskStatus.IsOpen = 1
and DatePost between '2014-01-20 00:00:00' and '2014-01-21 23:59:59') mk
group by
mk.DatePost, mk.kioskID,
mk.kioskIP, mk.agency

SQL query for insert into with a set of constants

It seems like there should be a query for this, but I can't think of how to do it.
I've got a table with a composite primary key consisting of two fields I'd like to populate with data,
I can do an insert into from one table to fill up half the keys, but I want to fill up the other half with a set of constants (0, 3, 5, 6, 9) etc...
so the end result would look like this
+--------------+
|AwesomeTable |
+--------------+
| Id1 | Id2 |
| 1 | 0 |
| 1 | 3 |
| 1 | 5 |
| 1 | 6 |
| 1 | 9 |
| 2 | 0 |
| 2 | 3 |
| ... | ... |
+--------------+
I've got as far as insert into awesometable (id1, id2) select id1, [need something here] from table1 [need something else here]
I've got a table with 2 primary keys
No, you don't. A table can only have one primary key. You probably mean a composite primary key.
I believe you want this:
INSERT
INTO awesometable (id1, id2)
SELECT t1.id1, q.id2
FROM table1 t1
CROSS JOIN
(
SELECT 0 AS id2
UNION ALL
SELECT 3
UNION ALL
SELECT 5
UNION ALL
SELECT 6
UNION ALL
SELECT 9
) q
, or in Oracle:
INSERT
INTO awesometable (id1, id2)
SELECT t1.id1, q.id2
FROM table1 t1
CROSS JOIN
(
SELECT 0 AS id2
FROM dual
UNION ALL
SELECT 3
FROM dual
UNION ALL
SELECT 5
FROM dual
UNION ALL
SELECT 6
FROM dual
UNION ALL
SELECT 9
FROM dual
) q
If I understand correctly, maybe you can use something like this:
insert into awesometable (id1, id2)
select id1, (select top 1 id2 from table2 where /*a condition here to retreive only one result*/)
from table1