开发者

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'
...
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜