select max id of each id - sql

I have two tables: tbComment and tbCommentStatus:
**tbComment**
CommentID IsLocked
1 0
2 0
3 1
4 0
5 1
**tbCommentStatus**
CommentStatusID CommentID StatusTypeID
105 1 1
106 1 4
107 2 1
108 3 1
109 3 4
110 4 1
112 5 1
112 5 4
I want to return CommentIDs of a dataset of the highest CommentStatusIDs for each CommentID Where StatusTypeID = 4 and IsLocked = 1.
Basically, here I would return CommentIDs: 3,5 because their highest CommentStatusID has a StatusTypeID=4 and tbComment.IsLocked=1
Man, I hope this makes sense. If it doesn't I can clarify.
Thanks!

Try the following query.
SELECT c.CommentID, MAX(cs.CommentStatusID) MaxCommentStatusID
FROM tbComment c
JOIN tbCommentStatus cs ON c.CommentID = cs.CommentID
WHERE c.IsLocked = 1
AND cs.StatusTypeID = 4
GROUP BY c.CommentID

Related

How to Update column Num with an incremental number in Master-Detail with row_number()?

I want to update my column Acc.DocHeader.Num and Acc.DocItem.Num with an incremental number. I have:
UPDATE x
SET x.Num = x.newNum,x.iNum=x.newNum
FROM (
SELECT Num,iNum, ROW_NUMBER() OVER (ORDER BY DocCreateDate ,DailyNum) AS newNum
FROM (SELECT h.Num,h.DocCreateDate,h.DailyNum,i.Num iNum FROM Acc.DocHeader h INNER JOIN Acc.DocItem i ON i.DocHeaderRef = h.Id WHERE h.Year = 1395 AND h.BranchRef = 1) AS header
) x
Why do I get Derived table 'x' is not updatable because the modification affects multiple base tables?
DocHeader Table :
Id Num Year DocCreateDate
-------------------------------------------------------
1 NULL 1396 2016-03-20
2 NULL 1395 2016-04-02
3 NULL 1395 2016-04-05
4 NULL 1395 2016-04-10
DocItem Table:
Id Num DocHeaderRef
----------------------------------------------
1 NULL 1
2 NULL 1
3 NULL 1
4 NULL 4
5 NULL 4
6 NULL 3
7 NULL 3
8 NULL 3
output:
DocHeader Table:
Id Num Year DocCreateDate
-------------------------------------------------------
1 1 1396 2016-03-20
2 1 1395 2016-04-02
3 2 1395 2016-04-05
4 3 1395 2016-04-10
DocItem Table:
Id Num DocHeaderRef
----------------------------------------------
1 1 1
2 1 1
3 1 1
4 3 4
5 3 4
6 4 3
7 4 3
8 4 3
You are attempting to update columns from two different tables in a single update statement:
Num comes from Acc.DocHeader
iNum comes from Acc.DocItem
In SQL Server, you can only update one table at a time in an UPDATE.
You can update multiple tables in a single transaction. You can also use the OUTPUT clause to capture the values from the rows being updated. This answers the question of why you cannot do what you want.
I find your query a bit hard to follow -- and your question doesn't explain what you are trying to do -- so it is hard to suggest alternatives.

re-indexing duplicate rows

Hi I have a table below;
ID length
1 1050
1 1000
1 900
1 600
2 545
2 434
3 45
3 7
4 5
I need an SQL code to make the below table
ID IDK length
1 1 1050
1 2 1000
1 3 900
1 4 600
2 1 545
2 2 434
3 1 45
3 2 7
4 1 5
IDK is the new column to reindexing the same ID according to ascending order of length.
Thank you very much
This is a pain in MS Access. Here is one way using a correlated subquery:
select t.*,
(select count(*)
from foo as t2
where t2.id = t.id and t2.length >= t.length
) as idk
from foo as t;

Row Act like Column Database Query

I have a Person table.Persons are good at some language and i give them weight.My table are as follows:
Person
ID Name Description
1 Rodra Some..
2 Rakib Some..
3 Samsad Some..
4 Foysal Some..
Language
TypeID TypeName
1 C#
2 Asp.Net
3 Python
4 JSP
5 Java
6 Jquery
7 Android
PersonSkill
ID PersonID TypeID Weight
1 1 1 60
2 1 3 50
3 1 7 40
4 2 1 80
5 2 2 70
6 3 1 90
7 3 2 50
8 4 1 60
9 4 2 50
10 4 6 40
11 4 7 55
Now i want to query those person who know c#(TypeId 1)>65 and Asp.net(TypeID 2)>65.How to do it?Anyone helps me greatly appreciated.
Select *
FROM person
WHERE EXISTS(SELECT * FROM PersonSkill WHERE PersonId = Person.Id AND TypeID = 1 AND Weight>65)
AND EXISTS(SELECT * FROM PersonSkill WHERE PersonId = Person.Id AND TypeID = 2 AND Weight>65)
select p.* from
person p
JOIN personSkill ps ON p.ID=ps.PersonID
JOIN Language l ON l.TypeID=ps.TypeID
WHERE (l.TypeName = 'c#' AND ps.weight>65)
AND
(l.TypeName = 'Asp.net' AND ps.weight>65)

Query to multiply certain sets of rows on a single table

I've got a bit of a complicated query that I'm struggling with. You will notice that the schema isn't the easiest thing to work with but it's what I've been given and there isn't time to re-design (common story!).
I have rows like the ones below. Note: The 3 digit value numbers are just random numbers I made up.
id field_id value
1 5 999
1 6 888
1 7 777
1 8 foo <--- foo so we want the 3 values above
1 9 don't care
2 5 123
2 6 456
2 7 789
2 8 bar <--- bar so we DON'T want the 3 values above
2 9 don't care
3 5 623
3 6 971
3 7 481
3 8 foo <--- foo so we want the 3 values above
3 9 don't care
...
...
n 5 987
n 6 654
n 7 321
n 8 foo <--- foo so we want the 3 values above
n 9 don't care
I want this result:
id result
1 999*888*777
3 623*971*481
...
n 987*654*321
Is this clear? So we have a table with n*5 rows. For each of the sets of 5 rows: 3 of them have values we might want to multiply together, 1 of them tells us if we want to multiply and 1 of them we don't care about so we don't want the row in the query result.
Can we do this in Oracle? Preferably one query.. I guess you need to use a multiplication operator (somehow), and a grouping.
Any help would be great. Thank you.
something like this:
select m.id, exp(sum(ln(m.value)))
from mytab m
where m.field_id in (5, 6, 7)
and m.id in (select m2.id
from mytab m2
where m2.field_id = 8
and m2.value = 'foo')
group by m.id;
eg:
SQL> select * from mytab;
ID FIELD_ID VAL
---------- ---------- ---
1 5 999
1 6 888
1 7 777
1 8 foo
1 9 x
2 5 123
2 6 456
2 7 789
2 8 bar
2 9 x
3 5 623
3 6 971
3 7 481
3 8 foo
3 9 x
15 rows selected.
SQL> select m.id, exp(sum(ln(m.value))) result
2 from mytab m
3 where m.field_id in (5, 6, 7)
4 and m.id in (select m2.id
5 from mytab m2
6 where m2.field_id = 8
7 and m2.value = 'foo')
8 group by m.id;
ID RESULT
---------- ----------
1 689286024
3 290972773
Same logic; just removed the hard-coded values. posting this answer thinking might be helpful to some others.
SELECT a.id,
exp(sum(ln(a.val)))
FROM mytab a,
(SELECT DISTINCT id,
field_id
FROM mytab
WHERE val = 'foo') b
WHERE a.id = b.id
AND a.field_id < b.field_id
GROUP BY a.id;

stored procedure to find value in 2 columns out of 3

I am putting in the samle date and i am supposed to do something similar what i am asking.
I want to run a query that would pull values in any two columns out 3 if it has a 1 or if any one column has a 1 it will return just those results. However it should search all three columns and in any of the three columns where it found value as 1 it should return that result. Can anyone please help me with this. Thanks in advance.
ID Patient Patient Name prio prio2 prio3
-------------------------------------------------
1 101563 Robert Riley 1 1 1
2 101583 Cody Ayers 1 0 1
3 101825 Jason Lawler 0 0 1
4 101984 Dustin Lumis 1 0 0
5 102365 Stacy smith 1 0 0
6 102564 Frank Milon 1 0 0
7 102692 Thomas Kroning 1 0 0
8 102856 Andrew Philips 1 0 0
9 102915 Alice Davies 0 0 1
10 103785 Jon Durley 0 0 1
11 103958 Clayton Folsom 1 1 1
12 104696 Michelle Holsley 1 1 1
13 104983 Teresa Jones 1 0 1
14 105892 Betsy Prat 1 1 0
15 106859 Casey Ayers 1 1 0
So, basically you want to pull anything where any of the 3 columns prio,prio2, or prio3 =1? Please clarify your question if this isn't what you are asking( for a better answer). Also, you should tag it with what type of SQL.
SELECT ID,Patient,[Patient Name],prio,prio2, prio3
FROM uRtable
WHERE prio = 1 OR prio2 = 1 OR prio3 = 1
But, if you are saying that you want to pull back any row where any of the 3 columns prio,prio2, or prio3 = 1, but at least one of them is 0 (Get any where any of the 3 = 1 but exclude where they all = 1), probably the easiest way to understand that would be
SELECT ID,Patient,[Patient Name],prio,prio2, prio3
FROM uRtable
WHERE (prio = 1 OR prio2 = 1 OR prio3 = 1)
AND (prio = 0 OR prio2 = 0 OR prio3 = 0)
Try this:
select * from mytable
where prio + prio2 + prio3 = (
select max(prio + prio2 + prio3)
from mytable
where prio = 1 or prio2 = 1 or prio3 = 1
)
SELECT *
FROM tbl
WHERE 1 IN (prio,prio2,prio3)