Find all foreign key rows from table that is referenced multiple times
I have the following database structure:
C开发者_开发百科REATE TABLE LookupTable
(
PK UNIQUEIDENTIFIER PRIMARY KEY,
)
CREATE TABLE MainTable
(
Lookup1 UNIQUEIDENTIFIER FOREIGN KEY REFERENCES LookupTable(PK),
Lookup2 UNIQUEIDENTIFIER FOREIGN KEY REFERENCES LookupTable(PK),
-- ...
-- ... LookupN UNIQUEIDENTIFIER FOREIGN KEY REFERENCES LookupTable(PK),
)
MainTable references LookupTable multiple times via separate columns.
If I insert the following data:
INSERT INTO LookupTable VALUES('11111111-1111-1111-1111-111111111111')
INSERT INTO LookupTable VALUES('22222222-2222-2222-2222-222222222222')
INSERT INTO MainTable VALUES('11111111-1111-1111-1111-111111111111','22222222-2222-2222-2222-222222222222')
INSERT INTO MainTable VALUES('22222222-2222-2222-2222-222222222222','11111111-1111-1111-1111-111111111111')
I want to be able to find every record in [MainTable] where ANY of the lookup fields is equal to '11111111-1111-1111-1111-111111111111' (this should return both rows in the example).
SQL is not my strong suit. Is there a simpler way of doing this than
SELECT * FROM MainTable WHERE
Lookup1 = '11111111-1111-1111-1111-111111111111'
OR
Lookup2 = '11111111-1111-1111-1111-111111111111'
-- ...
-- OR
-- LookupN = '11111111-1111-1111-1111-111111111111'
?
This seems tedious because it requires me to specify every lookup column by name before I can retrieve the results I want, and in my database there can be 20+ lookup columns in some circumstances.
There are three options:
- Query your tables the way you doing (many ORs)
- Build your query dynamically and execute it (like EXEC on SQL Server)
- Change your database schema and move the Lookup-columns from your MainTable to a third table
CREATE TABLE LookupTable
(
PK UNIQUEIDENTIFIER PRIMARY KEY,
)
CREATE TABLE MainTable
(
PK UNIQUEIDENTIFIER PRIMARY KEY,
)
CREATE TABLE MainTableLookup
(
MainTablePK UNIQUEIDENTIFIER FOREIGN KEY REFERENCES MainTable(PK),
Lookup UNIQUEIDENTIFIER FOREIGN KEY REFERENCES LookupTable(PK),
)
Then you can query like this:
SELECT
*
FROM
MainTable MT JOIN MainTableLookup ON MT.PK = MTL.MainTablePK
WHERE
EXISTS (SELECT 1 FROM LookupTable LT
WHERE LT.PK = MTL.Lookup
AND MTL.Lookup = '11111111-1111-1111-1111-111111111111')
One further suggestion. Doing a query with OR can lead to poor performance; it can be faster with a UNION:
SELECT * FROM MainTable WHERE
Lookup1 = '11111111-1111-1111-1111-111111111111'
UNION
SELECT * FROM MainTable WHERE
Lookup2 = '11111111-1111-1111-1111-111111111111'
...
精彩评论