I have the following tables:
CREATE TABLE forms
(
ID INT NOT NULL,
NAME TEXT NOT NULL,
TITLE TEXT NOT NULL
);
CREATE TABLE new_forms
(
ID INT NOT NULL,
NAME TEXT NULL,
TITLE TEXT NULL
);
INSERT INTO forms VALUES (0, 'test', 'test');
INSERT INTO new_forms VALUES (0, 'new_test', NULL);
And I'm using the following query:
INSERT INTO forms(id, name, title)
SELECT
1, COALESCE(nf.name, f.name), COALESCE(nf.title, f.title)
FROM
forms f
LEFT OUTER JOIN
new_forms nf ON nf.id = f.id;
SELECT * FROM forms;
The idea is to add both rows that match to the table.
In this example this two new records should be added:
1 test test
1 new_test test
But it's only adding the last one.
I have tried with all the join and none of them worked.
Fiddle
Thanks
You are using a join in the query which will give you only 1 row. If you need 2 rows. You have to use UNION ALL clause -
INSERT INTO forms(id, name, title)
SELECT
1, COALESCE(nf.name, f.name), COALESCE(nf.title, f.title)
FROM
forms f
LEFT OUTER JOIN
new_forms nf ON nf.id = f.id
UNION ALL
SELECT
1, COALESCE(f.name, nf.name), COALESCE(nf.title, f.title)
FROM
forms f
LEFT OUTER JOIN
new_forms nf ON nf.id = f.id;
Related
I am wondering if there is a better way to write this query. It achieves the target result but my colleague would prefer it be written without the subselects into temp tables t1-t3. The main "challenge" here is transposing the data from dbo.ReviewsData into a single row along with the rest of the data joined from dbo.Prodcucts and dbo.Reviews.
CREATE TABLE dbo.Products (
idProduct int identity,
product_title varchar(100)
PRIMARY KEY (idProduct)
);
INSERT INTO dbo.Products VALUES
(1001, 'poptart'),
(1002, 'coat hanger'),
(1003, 'sunglasses');
CREATE TABLE dbo.Reviews (
Rev_IDReview int identity,
Rev_IDProduct int
PRIMARY KEY (Rev_IDReview)
FOREIGN KEY (Rev_IDProduct) REFERENCES dbo.Products(idProduct)
);
INSERT INTO dbo.Reviews VALUES
(456, 1001),
(457, 1002),
(458, 1003);
CREATE TABLE dbo.ReviewFields (
RF_IDField int identity,
RF_FieldName varchar(32),
PRIMARY KEY (RF_IDField)
);
INSERT INTO dbo.ReviewFields VALUES
(1, 'Customer Name'),
(2, 'Review Title'),
(3, 'Review Message');
CREATE TABLE dbo.ReviewData (
RD_idData int identity,
RD_IDReview int,
RD_IDField int,
RD_FieldContent varchar(100)
PRIMARY KEY (RD_idData)
FOREIGN KEY (RD_IDReview) REFERENCES dbo.Reviews(Rev_IDReview)
);
INSERT INTO dbo.ReviewData VALUES
(79, 456, 1, 'Daniel'),
(80, 456, 2, 'Love this item!'),
(81, 456, 3, 'Works well...blah blah'),
(82, 457, 1, 'Joe!'),
(84, 457, 2, 'Pure Trash'),
(85, 457, 3, 'It was literally a used banana peel'),
(86, 458, 1, 'Karen'),
(87, 458, 2, 'Could be better'),
(88, 458, 3, 'I can always find something wrong');
SELECT P.product_title as "item", t1.ReviewedBy, t2.ReviewTitle, t3.ReviewContent
FROM dbo.Reviews R
INNER JOIN dbo.Products P
ON P.idProduct = R.Rev_IDProduct
INNER JOIN (
SELECT D.RD_FieldContent AS "ReviewedBy", D.RD_IDReview
FROM dbo.ReviewsData D
WHERE D.RD_IDField = 1
) t1
ON t1.RD_IDReview = R.Rev_IDReview
INNER JOIN (
SELECT D.RD_FieldContent AS "ReviewTitle", D.RD_IDReview
FROM dbo.ReviewsData D
WHERE D.RD_IDField = 2
) t2
ON t2.RD_IDReview = R.Rev_IDReview
INNER JOIN (
SELECT D.RD_FieldContent AS "ReviewContent", D.RD_IDReview
FROM dbo.ReviewsData D
WHERE D.RD_IDField = 3
) t3
ON t3.RD_IDReview = R.Rev_IDReview
EDIT: I have updated this post with the create statements for the tables as opposed to an image of the data (shame on me) and a more specific description of what exactly needed to be improved. Thanks to all for the comments and patience.
As others have said in comments, there is nothing objectively wrong with the query. However, you could argue that it's verbose and hard to read.
One way to shorten it is to replace INNER JOIN with CROSS APPLY:
INNER JOIN (
SELECT D.RD_FieldContent AS 'ReviewedBy', D.RD_IDReview
FROM dbo.ReviewsData D
WHERE D.RD_IDField = 1
) t1
ON t1.RD_IDReview = R.Rev_IDReview
APPLY lets you refer to values from the outer query, like in a subquery:
CROSS APPLY (
SELECT D.RD_FieldContent AS 'ReviewedBy'
FROM dbo.ReviewsData D
WHERE D.RD_IDField = 1 AND D.RD_IDReview = R.Rev_IDReview
) t1
I think of APPLY like a subquery that brings in new columns. It's like a cross between a subquery and a join. Benefits:
The query can be shorter, because you don't have to repeat the ID column twice.
You don't have to expose columns that you don't need.
Disadvantages:
If the query in the APPLY references outer values, then you can't extract it and run it all by itself without modifications.
APPLY is specific to Sql Server and it's not that widely-used.
Another thing to consider is using subqueries instead of joins for values that you only need in one place. Benefits:
The queries can be made shorter, because you don't have to repeat the ID column twice, and you don't have to give the output columns unique aliases.
You only have to look in one place to see the whole subquery.
Subqueries can only return 1 row, so you can't accidentally create extra rows, if only 1 row is desired.
SELECT
P.product_title as 'item',
(SELECT D.RD_FieldContent
FROM dbo.ReviewsData D
WHERE D.RD_IDField = 1 AND
D.RD_IDReview = R.Rev_IDReview) as ReviewedBy,
(SELECT D.RD_FieldContent
FROM dbo.ReviewsData D
WHERE D.RD_IDField = 2 AND
D.RD_IDReview = R.Rev_IDReview) as ReviewTitle,
(SELECT D.RD_FieldContent
FROM dbo.ReviewsData D
WHERE D.RD_IDField = 3 AND
D.RD_IDReview = R.Rev_IDReview) as ReviewContent
FROM dbo.Reviews R
INNER JOIN dbo.Products P ON P.idProduct = R.Rev_IDProduct
Edit:
It just occurred to me that you have made the joins themselves unnecessarily verbose (#Dale K actually already pointed this out in the comments):
INNER JOIN (
SELECT D.RD_FieldContent AS 'ReviewedBy', D.RD_IDReview
FROM dbo.ReviewsData D
WHERE D.RD_IDField = 1
) t1
ON t1.RD_IDReview = R.Rev_IDReview
Shorter:
SELECT RevBy.RD_FieldContent AS 'ReviewedBy'
...
INNER JOIN dbo.ReviewsData RevBy
ON RevBy.RD_IDReview = R.Rev_IDReview AND
RevBy.RD_IDField = 1
The originally submitted query is undoubtedly and unnecessarily verbose. Having digested various feedback from the community it has been revised to the following, working splendidly. In retrospect I feel very silly for having done this with subselects originally. I am clearly intermediate at best when it comes to SQL - I had not realized an "AND" clause could be included in the "ON" clause in a "JOIN" statement. Not sure why I would have made such a poor assumption.
SELECT
P.product_title as 'item',
D1.RD_FieldContent as 'ReviewedBy',
D2.RD_FieldContent as 'ReviewTitle',
D3.RD_FieldContent as 'ReviewContent'
FROM dbo.Reviews R
INNER JOIN dbo.Products P
ON P.idProduct = R.Rev_IDProduct
INNER JOIN dbo.ReviewsData D1
ON D1.RD_IDReview = R.Rev_IDReview AND D1.RD_IDField = 1
INNER JOIN dbo.ReviewsData D2
ON D2.RD_IDReview = R.Rev_IDReview AND D2.RD_IDField = 2
INNER JOIN dbo.ReviewsData D3
ON D3.RD_IDReview = R.Rev_IDReview AND D3.RD_IDField = 3
In my application I need to retrieve the best file from database with the following rules:
file, that has the most number of upvotes - priority 1
file, that has the most number of comments - priority 2
If there are only files that have no upvotes and no comments, then pick up just the random one.
My tables:
CREATE TABLE "FILES"
( "ID" NUMBER,
"OBJ_ID" NUMBER,
"NAME" VARCHAR2(30 BYTE)
) ;
CREATE TABLE "UPVOTES"
( "ID" NUMBER,
"TO_ID" NUMBER,
"TO_TYPE" NUMBER
) ;
COMMENT ON COLUMN "UPVOTES"."TO_TYPE" IS '0 obj, 1 file, 2 comment';
CREATE TABLE "COMMENTS"
( "ID" NUMBER,
"OBJ_ID" NUMBER,
"CONTENT" VARCHAR2(20 BYTE),
"TO_TYPE" NUMBER,
"TO_ID" NUMBER
) ;
COMMENT ON COLUMN "COMMENTS"."TO_TYPE" IS '0 object, 1 file';
Insert into FILES (ID,OBJ_ID,NAME) values ('1','1','best file for obj id = 1');
Insert into FILES (ID,OBJ_ID,NAME) values ('2','1','file obj1');
Insert into FILES (ID,OBJ_ID,NAME) values ('3','1','file obj1');
Insert into FILES (ID,OBJ_ID,NAME) values ('4','2','best file for obj id = 2');
Insert into FILES (ID,OBJ_ID,NAME) values ('5','2','file obj2');
Insert into FILES (ID,OBJ_ID,NAME) values ('6','3','only one file obj 3');
Insert into FILES (ID,OBJ_ID,NAME) values ('7','4','probilem file obj 4');
Insert into UPVOTES (ID,TO_ID,TO_TYPE) values ('1','1','1');
Insert into UPVOTES (ID,TO_ID,TO_TYPE) values ('2','1','1');
Insert into UPVOTES (ID,TO_ID,TO_TYPE) values ('3','7','0');
Insert into UPVOTES (ID,TO_ID,TO_TYPE) values ('4','2','0');
Insert into UPVOTES (ID,TO_ID,TO_TYPE) values ('5','2','0');
Insert into UPVOTES (ID,TO_ID,TO_TYPE) values ('6','2','0');
Insert into COMMENTS (ID,OBJ_ID,CONTENT,TO_TYPE,TO_ID) values ('1','1','comment 1','1','2');
Insert into COMMENTS (ID,OBJ_ID,CONTENT,TO_TYPE,TO_ID) values ('2','1','comment 2','1','2');
Insert into COMMENTS (ID,OBJ_ID,CONTENT,TO_TYPE,TO_ID) values ('3','2','comment 3','1','4');
My sql query:
SELECT obj_id, name FROM (
SELECT obj_id, name, rank, ROW_NUMBER() OVER (PARTITION BY obj_id ORDER BY rank) rownumb FROM (
SELECT f.obj_id, f.name, RANK() OVER (PARTITION BY f.obj_id ORDER BY COUNT(v.id) DESC, COUNT(DISTINCT com.id) DESC) rank
FROM files f
LEFT OUTER JOIN upvotes v
ON f.id = v.to_id
LEFT OUTER JOIN comments com
ON f.id = com.to_id
WHERE (v.to_type = 1 OR v.to_type IS NULL)
AND (com.to_type = 1 OR com.to_type IS NULL)
GROUP BY f.obj_id, f.name
)
)
WHERE rownumb = 1;
Expected result:
obj_id file name
1 best file for obj id = 1
2 best file for obj id = 2
3 only one file obj 3
4 probilem file obj 4
The problem is with the line:
(v.to_type = 1 OR v.to_type IS NULL)
It fails, because there are upvotes for objects (TO_TYPE = 0) with the same TO_ID as file ID, but I still need to count upvotes for files (TO_TYPE = 1).
Can somebody help me to figure it out?
I use Oracle Database 11g XE R2.
Replace
FROM files f
LEFT OUTER JOIN upvotes v
ON f.id = v.to_id
LEFT OUTER JOIN comments com
ON f.id = com.to_id
WHERE (v.to_type = 1 OR v.to_type IS NULL)
AND (com.to_type = 1 OR com.to_type IS NULL)
by
FROM files f
LEFT OUTER JOIN upvotes v ON f.id = v.to_id AND v.to_type = 1
LEFT OUTER JOIN comments com ON f.id = com.to_id AND com.to_type = 1
I can't find a way to describe my problem in an abstract and general manner, so I'll just provide a minimal example:
Let's say I have these 3 simple tables:
CREATE TABLE Document(
[Id] int IDENTITY(1, 1) NOT NULL PRIMARY KEY,
[Title] nvarchar(MAX),
[Patient] nvarchar(MAX)
);
CREATE TABLE Link(
DocumentId INT FOREIGN KEY REFERENCES Document(Id),
Text nvarchar(max)
);
CREATE TABLE ReadStatus(
DocumentId INT FOREIGN KEY REFERENCES Document(Id),
IsRead Bit NOT NULL,
UserId Int NOT NULL
);
We have a set of documents
A document can have 0 or more links
Documents can be read by users - this is tracked by the ReadStatus table, which associates a user with a document, and where IsRead=1 means the document has been read by that user and IsRead=0 means it hasn't been read by that user yet.
If, for document X and user A, a row does not exist in the ReadStatus table, we assume User A hasn't read document X yet.
Now, I need to run a query to select all patients. For each patient, I need the total number of documents available AND the number of documents that have already been read (i.e. IsRead=1). This is what I have so far:
SELECT d.Patient,
COUNT(DISTINCT d.Id) AS DocumentCount,
COUNT(NULLIF(rs.IsRead,0)) AS ReadDocumentCount,
COUNT(*) OVER () AS TotalPatientCount
FROM Document d
LEFT OUTER JOIN ReadStatus AS rs ON d.Id = rs.DocumentId AND rs.UserId = 123
INNER JOIN Link AS l ON d.Id = l.DocumentId AND l.Text IN ('Link W', 'Link X', 'Link T', 'Link Z')
GROUP BY d.Patient
The problem happens when a document (that has already been read) has more than one link. If that document has 3 links, the cartesian product produced by the INNER JOIN with the Link table will cause the ReadDocumentCount selection to be 3 instead of 1.
In other words, given this data:
INSERT INTO Document(Title, Patient) VALUES('Doc A', 'Mike')
INSERT INTO Document(Title, Patient) VALUES('Doc B', 'Mike')
INSERT INTO Link(DocumentId, Text) VALUES(1, N'Link W')
INSERT INTO Link(DocumentId, Text) VALUES(1, N'Link X')
INSERT INTO Link(DocumentId, Text) VALUES(1, N'Link Y')
INSERT INTO Link(DocumentId, Text) VALUES(2, N'Link Z')
INSERT INTO ReadStatus(DocumentID, IsRead, UserId) VALUES(1, 1, 123)
INSERT INTO ReadStatus(DocumentID, IsRead, UserId) VALUES(2, 0, 123)
I'm getting this as a result:
Patient DocumentCount ReadDocumentCount TotalPatientCount
Mike 2 3 1
Whereas this is what I want:
Patient DocumentCount ReadDocumentCount TotalPatientCount
Mike 2 1 1
SQL fiddle: http://sqlfiddle.com/#!6/e06bf/3
You can use COUNT(DISTINCT) conditionally as well:
SELECT d.Patient,
COUNT(DISTINCT d.Id) AS DocumentCount,
COUNT(DISTINCT (CASE WHEN rs.IsRead <> 0 THEN d.id END)) AS ReadDocumentCount,
COUNT(*) OVER () AS TotalPatientCount
FROM Document d LEFT OUTER JOIN
ReadStatus rs
ON d.Id = rs.DocumentId AND rs.UserId = 123 INNER JOIN
Link l
ON d.Id = l.DocumentId AND l.Text IN ('Link W', 'Link X', 'Link T', 'Link Z')
GROUP BY d.Patient;
Hello I have following SQL query
SELECT K.name AS Name, K.surname AS Surname, U1.akce AS Event,
U2.[text] AS [Scheme], U1.[text] AS [Registered under>],
( U1.x - (
SELECT Count(K.ubytov)
FROM klient
WHERE ubytov = U2.[text]) ) AS [Free space]
FROM klient K
INNER JOIN ubytov U1 ON U1.[text] = K.ubytov
LEFT OUTER JOIN ubytov U2 ON U1.z = U2.id WHERE U1.akce = '140012-02'
ORDER BY U1.[text]
I'm trying to achieve that in column Free space would be (value from ubytov.x that matches U1.z = U2.id) - (total number of rows from table klient that has the same value in U1.[text]=K.ubytov)
In table klient column ubytov I have values that matches ubytov.text and in ubytov.z I have value that matches ubytov.x in different row.
Would somebody help me solve this out please?
Thank you for your time.
An example:
Table klient
ID_K ubytov
1 RoomOwner
2 RoomOwner
table ubytov
id text x z
1 roomType1 2 NULL
2 RoomOwner NULL 1
Desired Output:
Name Surname Event Scheme Registered under: Free space
Nam1 Surname1 Even1 Scheme1 RoomOwnerName 0 // (because 2 counts from klient) - (roomType1 x)
Although, it wasn't much clear because of missing columns.
I tried to build the required query using a CTE expression.
Here is the sqlfiddle code.
Let me know, if this is what you are looking for.
create table klient
(
id_k int,
ubytov varchar(25)
)
go
create table ubytov
(
id int,
text varchar(25),
x int null,
z int null
)
go
insert into klient(id_k, ubytov)
select 1, 'RoomOwner'
union select 2, 'RoomOwner'
go
insert into ubytov(id, text, x, z)
select 1, 'roomType1', 2, null
union select 2, 'RoomOwner', null, 1
go
;WITH cte_klint_counts_by_ubytov
AS
(
SELECT
ubytov,
Count(ubytov) AS ubytovCount
FROM klient
GROUP BY ubytov
)
SELECT
U2.[text] AS [Scheme],
U1.[text] AS [Registered under>],
(isnull(U1.x, 0) - isnull(c.ubytovCount, 0)) AS [Free space]
FROM
klient K
INNER JOIN ubytov U1 ON U1.[text] = K.ubytov
LEFT OUTER JOIN ubytov U2 ON U1.z = U2.id
LEFT OUTER JOIN cte_klint_counts_by_ubytov c ON c.ubytov = U2.[text]
ORDER BY u1.[text]
I have 3 tables that I'm trying to create a query from:
Table 1 (iuieEmployee) ->position number
Table 2 (jbEmployeeH1BInfo) -> position number, LCA number, start date
Table 3 (jbEmployeeLCA) -> LCA number
Table 4 (jbInternationsl) -> Main demographic table
I have a query that works fine where there's only 1 record in each table, but tables 2 and 3 can have multiple records. I want it to find the record with he most recent start date and verify that there is a matching LCA number in the 3rd table and a matching position number int he first table and show me any records where this isn't the case. How can I accomplish this? I currently have:
SELECT DISTINCT jbInternational.idnumber, jbInternational.lastname, jbInternational.firstname, jbInternational.midname,
jbInternational.campus, jbInternational.universityid, jbInternational.sevisid, jbInternational.citizenship,
jbInternational.immigrationstatus, jbEmployeeH1BInfo.lcaNumber AS lcaNumber1, jbEmployeeLCA.lcaNumber AS lcaNumber2
FROM (select jbEmployeeH1BInfo.idnumber, MAX(jbEmployeeH1BInfo.approvalStartDate) AS MaxDateStamp FROM [internationalservices].[dbo].jbEmployeeH1BInfo GROUP BY idnumber ) my
INNER JOIN [internationalservices].[dbo].jbEmployeeH1BInfo WITH (nolock) ON my.idnumber=jbEmployeeH1BInfo.idnumber AND my.MaxDateStamp=jbEmployeeH1BInfo.approvalStartDate
INNER JOIN [internationalservices].[dbo].jbInternational WITH (nolock) ON jbInternational.idnumber=jbEmployeeH1BInfo.idnumber
inner join [internationalservices].[dbo].jbEmployeeLCA ON jbInternational.idnumber = jbEmployeeLCA.idnumber
WHERE jbInternational.idnumber not in(
SELECT DISTINCT jbInternational.idnumber
FROM (select distinct jbEmployeeH1BInfo.idnumber, MAX(jbEmployeeH1BInfo.approvalStartDate) AS MaxDateStamp
FROM [internationalservices].[dbo].jbEmployeeH1BInfo GROUP BY idnumber ) my
INNER JOIN [internationalservices].[dbo].jbEmployeeH1BInfo WITH (nolock) ON my.idnumber=jbEmployeeH1BInfo.idnumber AND my.MaxDateStamp=jbEmployeeH1BInfo.approvalStartDate
INNER JOIN [internationalservices].[dbo].jbInternational WITH (nolock) ON jbInternational.idnumber=jbEmployeeH1BInfo.idnumber
inner join [internationalservices].[dbo].jbEmployeeLCA ON jbInternational.idnumber = jbEmployeeLCA.idnumber
AND jbEmployeeH1BInfo.lcaNumber = jbEmployeeLCA.lcaNumber)
Table Schema:
create table iuieEmployee(idnumber int, POS_NBR varchar(8));
insert into iuieEmployee values(123456, '470V13');
insert into iuieEmployee values(123457, '98X000');
insert into iuieEmployee values(123458, '98X000');
insert into iuieEmployee values(123455, '98X000');
create table jbEmployeeH1BInfo (idnumber int, approvalStartDate smalldatetime, lcaNumber varchar(20), positionNumber varchar(200));
insert into jbEmployeeH1BInfo values (123456, 07/01/2012, '1-200-3000', '98X000');
insert into jbEmployeeH1BInfo values (123456, 07/30/2013, '1-200-4000', '470V13');
insert into jbEmployeeH1BInfo values (123457, 07/01/2012, '1-200-5000', '98X000');
insert into jbEmployeeH1BInfo values (123458, 07/01/2012, '1-200-6000', '98X000');
insert into jbEmployeeH1BInfo values (123455, 07/30/2014, '1-200-7000', '98X000');
insert into jbEmployeeH1BInfo values (123455, 07/01/2012, '1-200-8000', '470V13');
create table jbEmployeeLCA (idnumber int, lcaNumber varchar(20));
insert into jbEmployeeLCA values (123456, 1-200-3000);
insert into jbEmployeeLCA values (123456, 1-200-4111);
insert into jbEmployeeLCA values (123457, 1-200-5000);
insert into jbEmployeeLCA values (123458, 1-200-6000);
insert into jbEmployeeLCA values (123455, 1-200-7000);
insert into jbEmployeeLCA values (123455, 1-200-8000);
create table jbInternational(idnumber int);
insert into jbInternational values(123456);
insert into jbInternational values(123457);
insert into jbInternational values(123458);
insert into jbInternational values(123455);
Should only return 1 line:
123456, 07/30/2013, '1-200-4000'
but is instead returning two lines:
123456, 07/30/2013, '1-200-4000 (not matching 1-200-4111)
123456, 07/30/2013, '1-200-4000 (not matching 1-200-3000)
It shouldn't return the second row because the position number with the -3000 lca number doesn't have the most current date.
Your explanation is hard to understand. I guess if you could explain it well, then you could probably write the query yourself. Here's what I think you meant:
Employee contains the main records.
You want to find all idnumbers such that
idnumber is in International
the H1BInfo record with the most recent approvalStartDate does not have an LCA number matching the LCA record
The first thing to do is to simplify that H1BInfo table. We are only looking for the rows with the most recent approvalStartDate. We can do that by partitioning by idnumber and ordering by approvalStartDate:
with rankedH1BInfo as (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY jbEmployeeH1BInfo.idnumber
ORDER BY jbEmployeeH1BInfo.approvalStartDate desc) as r
FROM [internationalservices].[dbo].jbEmployeeH1BInfo
)
Let's only get the first row of each partition:
, MostRecentH1BInfo as (
SELECT * FROM rankedH1BInfo
WHERE r = 1
)
Now we can do the join to find all the good ones:
, goodIDs as (
SELECT i.idnumber
FROM [internationalservices].[dbo].jbInternational i WITH (NOLOCK)
JOIN [internationalservices].[dbo].jbEmployeeLCA l WITH (NOLOCK) on l.idnumber = i.idnumber
JOIN MostRecentH1BInfo h WITH (NOLOCK) on h.idnumber = i.idnumber
JOIN iuieEmployee e WITH (NOLOCK) on e.positionNumber = h.positionNumber
WHERE h.lcaNumber = l.lcaNumber
)
To put it all together and get the ones where this is false:
with rankedH1BInfo as (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY jbEmployeeH1BInfo.idnumber
ORDER BY jbEmployeeH1BInfo.approvalStartDate desc) as r
FROM [internationalservices].[dbo].jbEmployeeH1BInfo
), MostRecentH1BInfo as (
SELECT * FROM rankedH1BInfo
WHERE r = 1
), goodIDs as (
SELECT i.idnumber
FROM [internationalservices].[dbo].jbInternational i WITH (NOLOCK)
JOIN [internationalservices].[dbo].jbEmployeeLCA l WITH (NOLOCK) on l.idnumber = i.idnumber
JOIN MostRecentH1BInfo h WITH (NOLOCK) on h.idnumber = i.idnumber
JOIN iuieEmployee e WITH (NOLOCK) on e.positionNumber = h.positionNumber
WHERE h.lcaNumber = l.lcaNumber
)
SELECT DISTINCT jbInternational.idnumber, jbInternational.lastname, jbInternational.firstname, jbInternational.midname,
jbInternational.campus, jbInternational.universityid, jbInternational.sevisid, jbInternational.citizenship,
jbInternational.immigrationstatus, jbEmployeeH1BInfo.lcaNumber AS lcaNumber1, jbEmployeeLCA.lcaNumber AS lcaNumber2
FROM (select jbEmployeeH1BInfo.idnumber, MAX(jbEmployeeH1BInfo.approvalStartDate) AS MaxDateStamp FROM [internationalservices].[dbo].jbEmployeeH1BInfo GROUP BY idnumber ) my
INNER JOIN [internationalservices].[dbo].jbEmployeeH1BInfo WITH (nolock) ON my.idnumber=jbEmployeeH1BInfo.idnumber AND my.MaxDateStamp=jbEmployeeH1BInfo.approvalStartDate
INNER JOIN [internationalservices].[dbo].jbInternational WITH (nolock) ON jbInternational.idnumber=jbEmployeeH1BInfo.idnumber
inner join [internationalservices].[dbo].jbEmployeeLCA ON jbInternational.idnumber = jbEmployeeLCA.idnumber
WHERE jbInternational.idnumber not in (select idnumber from goodIDs)