PostgreSQL insert and ignore multiple columns - sql

I have newly created table with 4 unique fields: nsn, slug, part_no, mfg_sku.
I'm trying to insert into this table approx. 2 million rows from multiple tables, which has also repeating rows.
so the main question is...
how to emulate insert ignore in this case?
Select distinct based on multiple columns or what do you suggest?
Here is the data that I want to insert to Part table
SELECT "PartOld".id,
"PartOld"."PartNo",
"PartOld"."Manufacturer",
"PartOld"."Slug",
"PartOld"."Description",
"PartOld"."NSN",
NULL::numeric AS price,
"PartOld".name,
NULL::character varying AS mfg_sku
FROM "PartOld"
UNION
SELECT part_item.id,
NULL::character varying AS "PartNo",
part_item.manufacturer AS "Manufacturer",
NULL::character varying AS "Slug",
part_item.details AS "Description",
part_item.msn AS "NSN",
NULL::numeric AS price,
part_item.name,
part_item.mfg_sku
FROM part_item_fetched part_item
And Here is the Part table.
DROP TABLE IF EXISTS "electronic_parts"."Part";
CREATE TABLE "electronic_parts"."Part" (
"id" int4 NOT NULL DEFAULT nextval('"Part_id_seq"'::regclass),
"part_no" varchar COLLATE "default",
"manufacturer" varchar COLLATE "default",
"description" text COLLATE "default",
"slug" varchar COLLATE "default",
"nsn" varchar COLLATE "default",
"price" numeric,
"name" varchar COLLATE "default",
"mfg_sku" varchar COLLATE "default"
)
WITH (OIDS=FALSE);
ALTER TABLE "electronic_parts"."Part" OWNER TO "root";
-- ----------------------------
-- Primary key structure for table Part
-- ----------------------------
ALTER TABLE "electronic_parts"."Part" ADD PRIMARY KEY ("id") NOT DEFERRABLE INITIALLY IMMEDIATE;
-- ----------------------------
-- Indexes structure for table Part
-- ----------------------------
CREATE UNIQUE INDEX "part_u1" ON "electronic_parts"."Part" USING btree(part_no COLLATE "default" "pg_catalog"."text_ops" ASC NULLS LAST);
CREATE UNIQUE INDEX "part_u2" ON "electronic_parts"."Part" USING btree(nsn COLLATE "default" "pg_catalog"."text_ops" ASC NULLS LAST);
CREATE UNIQUE INDEX "part_u3" ON "electronic_parts"."Part" USING btree(mfg_sku COLLATE "default" "pg_catalog"."text_ops" ASC NULLS LAST);

Use
INSERT INTO ...
(SELECT ...)
ON CONFLICT DO NOTHING;
This has been available since 9.5, see the documentation.

You can filter your input with anti joins (tipically with NOT EXISTS() or LEFT JOIN + IS NULL):
WITH data AS (
-- your query here
SELECT ...
UNION ALL ...
),
conflicting_ids AS (
SELECT id FROM data GROUP BY id HAVING COUNT(*) > 1
),
conflicting_part_nos AS (
SELECT part_no FROM data GROUP BY part_no HAVING COUNT(*) > 1
),
conflicting_nsns AS (
SELECT nsn FROM data GROUP BY nsn HAVING COUNT(*) > 1
),
conflicting_mfg_skus AS (
SELECT mfg_sku FROM data GROUP BY mfg_sku HAVING COUNT(*) > 1
)
INSERT INTO table_name (column_names)
SELECT d.*
FROM data d
WHERE NOT EXISTS(SELECT 1 FROM conflicting_ids a WHERE a.id = d.id)
AND NOT EXISTS(SELECT 1 FROM conflicting_part_nos a WHERE a.part_no = d.part_no)
AND NOT EXISTS(SELECT 1 FROM conflicting_nsns a WHERE a.nsn = d.nsn)
AND NOT EXISTS(SELECT 1 FROM conflicting_mfg_skus a WHERE a.mfg_sku = d.mfg_sku)
ON CONFLICT DO NOTHING
Notes: id is unique too, because it is the primary key. Also, because the conflicting rows are checked separately, you won't need UNION. You can use UNION ALL, which will be a slightly more efficient.

Related

How to merge two columns in sql server

I want to merge two columns from deferent tables and when run my query shows this error:
Cannot resolve collation conflict for column 1 in SELECT statement
Here is my query
select (problems.name + department.dep_name) as m, usere.Use_name
, emp_problems.op_date
from usere, department, problems, emp_problems
where usere.id = emp_problems.users_id and emp_problems.prob_id = problems.id
and emp_problems.dup_dep_id = department.id
and emp_problems.emp_id = 37 and emp_problems.months = 11 and emp_problems.years =2020
You need to ALTER one of the columns to change the collation, or use COLLATE clause as
CREATE TABLE dbo.MyTable
(
MyCol1 VARCHAR(20) COLLATE Latin1_General_100_CI_AI_SC,
MyCol2 VARCHAR(20) COLLATE Latin1_General_100_CI_AI
);
Using ALTER:
ALTER TABLE dbo.MyTable
ALTER COLUMN MyCol2 VARCHAR(50) COLLATE Latin1_General_100_CI_AI_SC;
Using COLLATE clause:
INSERT INTO dbo.MyTable VALUES
('Foo', 'Bar');
/* This will throw the error */
SELECT CONCAT(MyCol1, MyCol2) FROM dbo.MyTable;
/* This won't */
SELECT CONCAT(MyCol1, MyCol2 COLLATE Latin1_General_100_CI_AI_SC) FROM dbo.MyTable;
Take a look at Set or Change the Column Collation
Here is a db<>fiddle

ORACLE 12c Unique constraint failing in MERGE command which is matching all columns from the index

I have a table of aggregated data which were collected incorrectly and I am trying to merge results of select into it and I am hitting constraint violation and probably missing something obvious.
Table is simple:
CREATE TABLE "DVRA_STATS_AGG_HOURLY"
( "ID" NUMBER(*,0),
"SHIPMENTS" NUMBER,
"EVENT_DATETIME" DATE,
"COUNTRY" VARCHAR2(2 CHAR),
"DATA_TYPE" VARCHAR2(3 CHAR),
"EVENT_TYPE" CHAR(15)
)
CREATE UNIQUE INDEX "DVRA_STATS_AGG_HOURLY_PK" ON "DVRA_STATS_AGG_HOURLY" ("ID")
CREATE UNIQUE INDEX "DVRA_STATS_AGG_HOURLY_UK1" ON "DVRA_STATS_AGG_HOURLY" ("EVENT_DATETIME", "COUNTRY", "DATA_TYPE", "EVENT_TYPE")
CREATE INDEX "DVRA_STATS_AGG_HOURLY_INDEX1" ON "DVRA_STATS_AGG_HOURLY" ("EVENT_DATETIME" DESC)
With trigger sequence and trigger
CREATE OR REPLACE EDITIONABLE TRIGGER "DVRA_STATS_AGG_HOURLY_AINC"
BEFORE INSERT ON dvra_stats_agg_hourly
FOR EACH ROW
BEGIN
SELECT stats_seq.NEXTVAL
INTO :new.id
FROM dual;
END;
Merge is not complicated either:
MERGE INTO dvra_stats_agg_hourly stats
USING(
SELECT COUNT(*) as SHIPMENTS, TRUNC(event_datetime,'HH24') as event_datetime,COUNTRY,data_type,event_type
FROM AUDIT
WHERE event_type in (<List of events>)
and TRUNC(event_datetime,'HH24') < trunc(sysdate,'HH24')
and audittable.event_datetime is not null
and audittable.COUNTRY is not null
and audittable.data_type is not null
and audittable.event_type is not null
GROUP BY TRUNC(event_datetime,'HH24'),COUNTRY,data_type,event_type
) audittable
ON (
audittable.event_datetime = stats.event_datetime
and audittable.COUNTRY = stats.COUNTRY
and audittable.data_type = stats.data_type
and audittable.event_type = stats.event_type
)
WHEN MATCHED THEN
UPDATE SET stats.SHIPMENTS = audittable.SHIPMENTS WHERE stats.SHIPMENTS <> audittable.SHIPMENTS
WHEN NOT MATCHED THEN
INSERT (SHIPMENTS,event_datetime,STATS.COUNTRY,data_type,event_type)
VALUES (audittable.SHIPMENTS,audittable.event_datetime,audittable.COUNTRY ,audittable.data_type ,audittable.event_type)
;
And I am getting error:
ORA-00001: unique constraint (DVRA_MONITORING.DVRA_STATS_AGG_HOURLY_UK1) violated
I am matching on same columns as I am using in unique constraint. I am inserting only not matching rows and I am grouping by same columns so there should be only one row for unique combination of those columns.
I am only one updating table when I am doing this operation, so no other session manipulating data during run of the query.
What am I missing here?
Edit: Data in DVRA_STATS_AGG_HOURLY were inserted with insert into select. With same select which is used in this merge. Just some data were not properly loaded yet, so I am making correction.
Edit2: added not null
Edit3: Changes in merge query after discussion with Alex
MERGE INTO dvra_stats_agg_hourly stats
USING(
SELECT COUNT(*) as SHIPMENTS, TRUNC(event_datetime,'HH24') as event_datetime,COUNTRY,data_type,event_type
FROM BCTCUSTOM.V_DVRA_AUDIT
WHERE event_type in (<List of types>)
and TRUNC(event_datetime,'HH24') < trunc(sysdate,'HH24')
and TRUNC(event_datetime,'HH24') is not null
and event_datetime is not null
and COUNTRY is not null
and data_type is not null
and event_type is not null
GROUP BY TRUNC(event_datetime,'HH24'),COUNTRY,data_type,event_type
) audittable
ON (
audittable.event_datetime = stats.event_datetime
and ((audittable.COUNTRY is null and stats.COUNTRY is null) or audittable.COUNTRY = stats.COUNTRY)
and ((audittable.data_type is null and stats.data_type is null) or audittable.data_type = stats.data_type)
and ((audittable.event_type is null and stats.event_type is null) or audittable.event_type = stats.event_type)
)
WHEN MATCHED THEN
UPDATE SET stats.SHIPMENTS = audittable.SHIPMENTS WHERE stats.SHIPMENTS <> audittable.SHIPMENTS
WHEN NOT MATCHED THEN
INSERT (SHIPMENTS,event_datetime,STATS.COUNTRY,data_type,event_type)
VALUES (audittable.SHIPMENTS,audittable.event_datetime,audittable.COUNTRY ,audittable.data_type ,audittable.event_type)
;
If any of the four columns you are comparing in your ON clause are null then they won't match with your current conditions, since null = null is unknown.
You can add explicit null checks; instead of:
ON (
audittable.event_datetime = stats.event_datetime
and audittable.COUNTRY = stats.COUNTRY
and audittable.data_type = stats.data_type
and audittable.event_type = stats.event_type
)
do something like:
ON (
audittable.event_datetime = stats.event_datetime
and ((audittable.COUNTRY is null and stats.COUNTRY is null)
or audittable.COUNTRY = stats.COUNTRY)
and ((audittable.data_type is null and stats.data_type is null)
or audittable.data_type = stats.data_type)
and ((audittable.event_type is null and stats.event_type is null)
or audittable.event_type = stats.event_type)
)
db<>fiddle without nulls - works OK.
db<>fiddle with nulls - initially fails, but works with explicit null checks added.
Another possibility is a data type mismatch, as you're using CHAR(15) in the table you showed. If the audit table has that column defined as VARCHAR2(15) instead then the comparison will also fail (because "Oracle uses nonpadded comparison semantics whenever one or both values in the comparison have the data type VARCHAR2 or NVARCHAR2"), and the implicit conversion during the insert will cause the constraint violation. In that case, you can trim the CHAR value:
ON (
audittable.event_datetime = stats.event_datetime
and audittable.COUNTRY = stats.COUNTRY
and audittable.data_type = stats.data_type
and audittable.event_type = trim(stats.event_type)
)
db<>fiddle

Implementing an Aliases table (self-referencing many-to-many)

I am trying to model an Alias relationship. That is, several records in my person table may represent the same actual person. I don't care who the "Primary" person is. All Person records would carry equal weight.
I have implemented this in the past with the two tables you see below.
------------- ------------
| Person | | Alias |
|-----------| |----------|
| PersonID | | AliasID |
| LastName | | PersonID |
| FirstName | ------------
-------------
Here is some sample data:
Person (1, 'Joseph', 'Smith')
Person (2, 'Jane', 'Doe')
Person (3, 'Joe', 'Smith')
Person (4, 'Joey', 'Smith')
Alias(1, 1)
Alias(1, 3)
Alias(1, 4)
I suppose I could move the AliasID to the Person table since there is a 1-to-1 relationship between the PersonID fields. However, I may want to add additional fields to the Alias table (like Sequence number, etc.) at some point in the future.
Is there a better way to model this than what I have here?
This is how I would do it.
--DROP TABLE [dbo].[Alias]
GO
--DROP TABLE [dbo].[RealPerson]
GO
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'[dbo].[RealPerson]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
BEGIN
DROP TABLE [dbo].[RealPerson]
END
GO
CREATE TABLE [dbo].[RealPerson]
(
RealPersonUUID [UNIQUEIDENTIFIER] NOT NULL DEFAULT NEWSEQUENTIALID()
, CreateDate smalldatetime default CURRENT_TIMESTAMP
, MyCompanyFriendlyUniqueIdentifier varchar(128) not null
)
GO
ALTER TABLE dbo.RealPerson ADD CONSTRAINT PK_RealPerson
PRIMARY KEY NONCLUSTERED (RealPersonUUID)
GO
ALTER TABLE [dbo].[RealPerson]
ADD CONSTRAINT CK_MyCompanyFriendlyUniqueIdentifier_Unique UNIQUE (MyCompanyFriendlyUniqueIdentifier)
GO
GRANT SELECT , INSERT, UPDATE, DELETE ON [dbo].[RealPerson] TO public
GO
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'[dbo].[Alias]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
BEGIN
DROP TABLE [dbo].[Alias]
END
GO
CREATE TABLE [dbo].[Alias]
(
AliasUUID [UNIQUEIDENTIFIER] NOT NULL DEFAULT NEWSEQUENTIALID()
, RealPersonUUID [UNIQUEIDENTIFIER] NOT NULL
, CreateDate smalldatetime default CURRENT_TIMESTAMP
, LastName varchar(128) not null
, FirstName varchar(128) not null
, PriorityRank smallint not null
)
GO
ALTER TABLE dbo.Alias ADD CONSTRAINT PK_Alias
PRIMARY KEY NONCLUSTERED (AliasUUID)
GO
ALTER TABLE [dbo].[Alias]
ADD CONSTRAINT FK_AliasToRealPerson
FOREIGN KEY (RealPersonUUID) REFERENCES dbo.RealPerson (RealPersonUUID)
GO
ALTER TABLE [dbo].[Alias]
ADD CONSTRAINT CK_RealPersonUUID_PriorityRank_Unique UNIQUE (RealPersonUUID,PriorityRank)
GO
ALTER TABLE [dbo].[Alias]
ADD CONSTRAINT CK_PriorityRank_Range CHECK (PriorityRank >= 0 AND PriorityRank < 33)
GO
if exists (select * from dbo.sysindexes where name = N'IX_Alias_RealPersonUUID' and id = object_id(N'[dbo].[Alias]'))
DROP INDEX [dbo].[Alias].[IX_Alias_RealPersonUUID]
GO
CREATE INDEX [IX_Alias_RealPersonUUID] ON [dbo].[Alias]([RealPersonUUID])
GO
GRANT SELECT , INSERT, UPDATE, DELETE ON [dbo].[Alias] TO public
GO
INSERT INTO dbo.RealPerson ( RealPersonUUID , MyCompanyFriendlyUniqueIdentifier )
select '11111111-1111-1111-1111-111111111111' , 'ABC'
union all select '22222222-2222-2222-2222-222222222222' , 'DEF'
INSERT INTO dbo.[Alias] ( RealPersonUUID , LastName, FirstName , PriorityRank)
select '11111111-1111-1111-1111-111111111111' , 'Smith' , 'Joseph' , 0
union all select '11111111-1111-1111-1111-111111111111' , 'Smith' , 'Joey' , 1
union all select '11111111-1111-1111-1111-111111111111' , 'Smith' , 'Joe' , 2
union all select '11111111-1111-1111-1111-111111111111' , 'Smith' , 'Jo' , 3
union all select '22222222-2222-2222-2222-222222222222' , 'Doe' , 'Jane' , 0
select 'Main Identity' as X, * from dbo.RealPerson rp join dbo.[Alias] al on rp.RealPersonUUID = al.RealPersonUUID where al.PriorityRank = 0
select 'All Identities' as X, * from dbo.RealPerson rp join dbo.[Alias] al on rp.RealPersonUUID = al.RealPersonUUID
select 'Aliai Only' as X, * from dbo.RealPerson rp join dbo.[Alias] al on rp.RealPersonUUID = al.RealPersonUUID where al.PriorityRank > 0
First, you should identify your entities. Clearly you have a person and each person will have their own identity. They are unique and should allways be kept as such. Then you have Alias's They should be in their own table with a one to many relationship. This should be enfrced with primary keys, forgien keys, indexes for quick lookup where appropriate. Each table need a clustered index also for performance. You should then use stored procedures to return or update the tables. I've intentionally used certain word, because if you google them, you will get lots of good information on what you need to do.

How to prevent an entry in one table from existing in another table

I have 3 tables in SQL Server 2008
Clubs with a PK of ID and a Name.
Products which has a PK of ID, a FK of ClubID , a Name, a ShortCode and a Keyword.
There is a UK to enforce that there are no duplicate keywords for combinations of ShortCode/Keyword.
ProductAdditionalShortCodes. This has a PK of ID, a FK of ProductID and a Keyword
The idea is to prevent any shortcode/keyword combination of products to point to different clubs and also to prevent the creation of duplicate short/code keyword combinations
I have a solution that works, but feels clunky, and could under certain circumstances fail if multiple users happened to update multiple entries at the same time. (Hypothetically)
How can I add some form of constraint to the DB to prevent the Keyword in the Main table from being the same as in the Additional table and the other way round?
Following is a sample script to create the scenario and some of the examples I want to prevent. I am not opposed to changing the DB design if the impact of the change would not disrupt too many other aspects of the solution. (I realize this is subjective)
use Tinker
if exists (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'dbo.ProductAdditionalKeywords') AND type in (N'U'))
drop table dbo.ProductAdditionalKeywords
go
if exists (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'dbo.Products') AND type in (N'U'))
drop table dbo.Products
go
if exists (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'dbo.Clubs') AND type in (N'U'))
drop table dbo.Clubs
go
create table dbo.Clubs (
ID int not null identity(1,1)
,Name varchar(50) not null
,constraint PK_Clubs primary key clustered ( ID )
)
go
alter table dbo.Clubs add constraint UK_Clubs__Name unique ( Name )
go
create table dbo.Products (
ID int not null identity(1,1)
,ClubID int not null
,Name varchar(50) not null
,ShortCode varchar(50) not null
,Keyword varchar(50) not null
,constraint PK_Products primary key clustered ( ID )
)
go
alter table dbo.Products add constraint UK_Products__ShortCode_Keyword unique ( ShortCode , Keyword )
go
alter table dbo.Products add constraint UK_Products__Name unique ( Name )
go
alter table dbo.Products add constraint FK_Products_ClubID foreign key ( ClubID ) references dbo.Clubs ( ID )
go
create table dbo.ProductAdditionalKeywords (
ID int not null identity(1,1)
,ProductID int not null
,Keyword varchar(50) not null
,constraint PK_ProductAdditionalKeywords primary key clustered ( ID )
)
go
alter table dbo.ProductAdditionalKeywords add constraint FK_ProductAdditionalKeywords_ProductID foreign key ( ProductID ) references dbo.Products ( ID )
go
alter table dbo.ProductAdditionalKeywords add constraint UK_ProductAdditionalKeywords__Keyword unique ( Keyword )
go
insert into dbo.Clubs ( Name )
select 'Club 1'
union all select 'Club 2'
insert into dbo.Products (ClubID,Name,Shortcode,Keyword)
select 1,'Product 1','001','P1'
union all select 1,'Product 2','001','P2'
union all select 1,'Product 3','001','P3'
union all select 2,'Product 4','002','P4'
union all select 2,'Product 5','002','P5'
union all select 2,'Product 6','002','P6'
insert into dbo.ProductAdditionalKeywords (ProductID,Keyword)
select 1,'P1A'
union all select 1,'P1B'
union all select 2,'P2A'
union all select 2,'P2B'
/*
What can be done to prevent the following statements from beeing allowed based on the reason in the comments?
*/
--insert into dbo.ProductAdditionalKeywords (ProductID,Keyword) values ( 1 , 'P2' ) -- Main keyword for product 2
--update dbo.Products set Keyword = 'P1A' where ID = 2 -- Additional keyword for product 1
--insert into dbo.ProductAdditionalKeywords (ProductID,Keyword) values ( 3 , 'P1' ) -- Main ShortCode/Keyword combination for product 1
/*
At the moment I look at the following view to see if the proposed(new/updated) Keyword/Shortcode combination already exists
If it already exists I pevent the insert/update
Is there any way to do it in the DB via constraints rather than in the BLL?
*/
select ShortCode,Keyword,count([ClubID]) as ClubCount from
(
select p.ClubID,p.ShortCode,p.Keyword,p.ID
from dbo.Products p
union all
select p.ClubID,p.ShortCode,PAK.Keyword,PAK.ID * -1
from dbo.ProductAdditionalKeywords as PAK
inner join dbo.Products P on PAK.ProductID = P.ID
) as FullList
group by Shortcode,Keyword
order by Shortcode,Keyword
How I would normally do this would be to place all of the keywords in a separate table (e.g. what is currently your additional table). If all keywords must be distinct within a ShortCode, then I'd include ShortCode in this table also, so that a unique constraint can be applied across both columns.
If all keywords for a product must be in the same ShortCode, then I'd keep ShortCode in Products also. I'd apply a unique constraint on (ID,ShortCode) in that table, and an additional foreign key from the keywords table, referencing both columns on both sides.
What we're left with now are two potential issues not included in your original design, but I don't know if they're a concern in practice:
1) Is the Keyword in Products more important, or special, than the additional keywords? If so, we need to add a column to keywords table to mark which one is important. To ensure only one is set, you can search for plenty of other SO questions which involve unique constraints with additional conditions. (Let me know if you can't find one and need it, I'm sure I can add a link if necessary)
2) Should a Product be allowed to have no keywords? If not, then I'd create a view that mimics your original Products table. In this circumstance, it would be easier if 1) above is true, in which case we always join to the "important" keyword. Otherwise, we need to have some way to limit it to a single row per product. We deny insert/update/delete on the table, and only allow them through the view. 3 relatively simple triggers will then maintain the underlying table structure.
on your design, I do not understand the the use of productAdditionalShortCodes having no field of ShortCode.
However, you can add Unique key constraint with ShortCode & Keyword (composite key). This will eliminate duplicate entry in product table.

Find all foreign key rows from table that is referenced multiple times

I have the following database structure:
CREATE 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'
...