I am trying to understand SQL better and have run into a problem when it comes to key-value pairs (I think there is a better term for this, but am not sure).
Contract | Contract Type | Column1 | Column2 |
---|---|---|---|
Contract 1 | Type 1 | x | |
Contract 1 | Type 2 | x | |
Contract 2 | Type 1 | x | |
Contract 2 | Type 2 | x |
I apologize if this example isn’t clear. I know there might be a way to set up this table better, however this is just an example I made up.
I am trying to create an SQL query that checks whether contracts are set up correctly. As an example, Contract 1 is set up correctly, as there is an x in column1 when it says ‘type 1’, and an x in column2 when it says ‘type 2’.
However, I am unsure how to write the CASE statement for Contract 2, as it requires checking each contract individually to see if either row has an ‘x’ in the correct places.
So far I’ve written the CASE statements for when there’s no ‘x’s in either row, and ‘x’s in both:
SELECT DISTINCT Table1.Contract,
Table1.ContractType,
Table1.Column1,
Table1.Column2,
Table1.Site
Table1.Date,
CASE
WHEN Column1 <> 'x' AND Column2 <> 'x' THEN 'Error'
WHEN Column1 = 'x' AND Column2 = 'x' THEN 'Error'
END AS 'Results'
FROM...
JOIN...
WHERE Contract IN (
SELECT Contract
FROM Table1
WHERE ContractType IN ('Type1','Type2','Type3') AND
Site = 'Site 1' AND
Contract HAVING COUNT(DISTINCT ContractType) >= 2
) AND Date >= CURRENT_TIMESTAMP
ORDER BY Contract
How do I check per Contract that there is x in Column1 for the first row and check that there is an x in Column2 for the second row?
Thank you!
EDIT: Edited in the ‘full query’, with some abstraction as to not show real data.
Something that I might have poorly explained: Technically, it would be okay if Column2 has an ‘x’ in a Type1 row and vice versa. The important part is that for each Contract, there’s an ‘x’ in both columns, via different rows.
2
Answers
Based on the new requirements (which I believe are as follows
Each row must have a value in column1 or column2
Contract type can not be repeated
there should be 2 rows
based on code this may need to be 3 or more columns in the first bullet
Here is the code to solve:
Note — based on the query above if you wanted the other columns that are not in the group by you would need to make this a subquery joined to the main query on Contract — to only pull the correct ones OR add a not around the where clauses to only pull the bad ones.
You need to use
GROUP BY
to define groups of rows, and then a applyCASE
clause to check whether contracts are set up correctly or not :Your table schema is "EAV" or Entity-Attribute-Value. This is a common schema for applications to use if the number of attributes per entity is unknown or volatile