4

I have a few database rows like this in the Employee table:

EmpId       Name        Information
1           Eric       {“Experience”: [{“Title”: “Assistant Accountant”, “Company”: “ComA”, “YearsOfExperience”: 3}, {“Title”: “Accountant”, “Company”: “ComB”, “YearsOfExperience”: 2}], “EmployedYear”:2016}
2           John       {“Experience”: [{“Title”: “Tech Engineer”, “Company”: “ComX”, “Years”: 5}, {“Title”: “Senior Tech Engineer”, “Company”: “ComY”, “YearsOfExperience”: 2}], “EmployedYear”:2012}
3           Leonard    {“Experience”: [{“Title”: “Junior Engineer”, “Company”: “ComJ”, “Years”: 2}, {“Title”: “Tech Engineer”, “Company”: “ComB”, “YearsOfExperience”: “7”}], “EmployedYear”:2017}

How do I select employees who have not worked in ComB?

What would be query for this? So far I got nothing because of this complex nested JSON array.

I'm trying now:

SELECT Name, Id 
FROM Employee
OUTER APPLY OPENJSON(Information, '$.Experience') WITH (
   Title nvarchar(max) '$.Title', 
   Company nvarchar(max) '$.Company', 
   YearsOfExperience int '$.YearsOfExperience'
) AS [Info]
WHERE [Info].Company != 'ComB'
4
  • Use OPENJSON. This JSON isn't particularly complex, so at least so us why what you have isn't working. Commented Jun 18, 2020 at 9:15
  • 1
    FYI, doesn't used stylised double quotes ( and ) for your JSON, as some parses won't be able to read them. Use unstylised double quotes ("). Commented Jun 18, 2020 at 9:26
  • Eric and Leonard have working experience in ComB. Are you sure about the question (How do I select employees who have not worked in ComB, in this case they're Eric and Leonard?)? Commented Jun 18, 2020 at 9:32
  • Thanks everyone, solved it, I should have used Exist check Commented Jun 18, 2020 at 9:38

3 Answers 3

3

You may try to use EXISTS() and OPENJSON().

Table:

CREATE TABLE Employee (
    EmpId int,       
    Name varchar(100),        
    Information varchar(1000)
)
INSERT INTO Employee (EmpId, Name, Information)
VALUES
    (1, 'Eric',    '{"Experience":[{"Title":"Assistant Accountant","Company":"ComA","YearsOfExperience":3},{"Title":"Accountant","Company":"ComB","YearsOfExperience":2}],"EmployedYear":2016}'),
    (2, 'John',    '{"Experience":[{"Title":"Tech Engineer","Company":"ComX","Years":5},{"Title":"Senior Tech Engineer","Company":"ComY","YearsOfExperience":2}],"EmployedYear":2012}'),
    (3, 'Leonard', '{"Experience":[{"Title":"Junior Engineer","Company":"ComJ","Years":2},{"Title":"Tech Engineer","Company":"ComB","YearsOfExperience":"7"}],"EmployedYear":2017}')

Statement:

SELECT Name, EmpId 
FROM Employee
WHERE NOT EXISTS (
   SELECT 1
   FROM OPENJSON(Information, '$.Experience') WITH (
     Title nvarchar(max) '$.Title', 
     Company nvarchar(max) '$.Company', 
     YearsOfExperience int '$.YearsOfExperience'
   ) AS [Info]
   WHERE [Info].Company = 'ComB'
)
Sign up to request clarification or add additional context in comments.

Comments

0

One method is with some conditional aggregation in a HAVING clause`:

SELECT V.EmpId,
       V.Name
FROM (VALUES(1,'Eric',N'{"Experience": [{"Title": "Assistant Accountant", "Company": "ComA", "YearsOfExperience": 3}, {"Title": "Accountant", "Company": "ComB", "YearsOfExperience": 2}], "EmployedYear":2016}'),
            (2,'John',N'{"Experience": [{"Title": "Tech Engineer", "Company": "ComX", "Years": 5}, {"Title": "Senior Tech Engineer", "Company": "ComY", "YearsOfExperience": 2}], "EmployedYear":2012}'),
            (3,'Leonard',N'{"Experience": [{"Title": "Junior Engineer", "Company": "ComJ", "Years": 2}, {"Title": "Tech Engineer", "Company": "ComB", "YearsOfExperience": "7"}], "EmployedYear":2017}'))V(EmpId,[Name],Information)
     CROSS APPLY OPENJSON(Information,'$.Experience')
     WITH (Title nvarchar(50),
           Company nvarchar(50),
           Years int) OJ
GROUP BY V.EmpId, V.Name
HAVING COUNT(CASE OJ.Company WHEN 'ComB' THEN 1 END) = 0;

Comments

0

You can use openjson() and a lateral join. You don't need to extract all attributes from the nested objects, since you are only intersted in the company name:

select e.empId, e.Name
from employee e
where exists (
    select 1
    from openjson(information, '$.Experience') with(company nvarchar(max) '$.Company')
    where company = 'ComB'
)

Demo on DB Fiddle:

empId | Name   
----: | :------
    1 | Eric   
    3 | Leonard

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.