【发布时间】:2012-01-04 17:34:10
【问题描述】:
请注意下面的 2 个查询。第一个对 4 个查询进行联合。我正在尝试根据以“@”为前缀的 3 个 SQL 变量为搜索条件编写 #2。因此,我们必须在搜索时考虑所有 3 个参数,而不是进行联合。如果任何参数/变量为 ''(或 NULL),则忽略该条件,但仍执行搜索。但所有字段都必须相互组合,才能在搜索结果中形成单行/记录。
如何重写 QUERY #2 以便它根据搜索条件(@companyName、@primaryPhone 和 @postalCode)提取结果?我认为 where 子句中的每个部分都必须有一些 OR 条件(因此它不会跳过 ''/NULL 搜索条件的行),但我很好奇这通常是如何完成的。 where 子句的 @primaryPhone 部分有点棘手,因为它同时查看电话和传真。
查询 #1
SELECT tempTable.optionValue, tempTable.optionText FROM (
SELECT
address.addressid AS 'optionValue',
address.name AS 'optionText'
FROM
dbo.address
WHERE
addressid=1
UNION
-- Company Name internal partial match
SELECT
address.addressid AS 'optionValue',
('[' + CAST(address.addressid AS NVARCHAR(10)) + '] ' + ISNULL(address.name,'') + ', ' + ISNULL(address1,'') + ', ' + ISNULL(city,'') + ' ' + ISNULL(statecode,'') + ', ' + ISNULL(countrycode,'') + ' ' + ISNULL(postalcode,'')) AS 'optionText'
FROM
dbo.[address]
LEFT OUTER JOIN dbo.contact_address ON dbo.address.addressid = dbo.contact_address.addressid
LEFT OUTER JOIN dbo.clientcontact ON dbo.contact_address.contactid = dbo.clientcontact.contactid
LEFT OUTER JOIN dbo.client ON dbo.clientcontact.clientid = dbo.client.clientid
LEFT OUTER JOIN dbo.contact ON dbo.contact_address.contactid = dbo.contact.contactid
WHERE
client.name IS NOT NULL
AND client.name != ''
AND @companyName != ''
AND @companyName IS NOT NULL
AND client.name LIKE '%' + @companyName + '%'
AND clientcontact.contacttypeid = 3 --primary contacts only
UNION
-- Primary Phone/Fax internal partial match
SELECT
address.addressid AS 'optionValue',
('[' + CAST(address.addressid AS NVARCHAR(10)) + '] ' + ISNULL(address.name,'') + ', ' + ISNULL(address1,'') + ', ' + ISNULL(city,'') + ' ' + ISNULL(statecode,'') + ', ' + ISNULL(countrycode,'') + ' ' + ISNULL(postalcode,'')) AS 'optionText'
FROM
dbo.[contact]
LEFT OUTER JOIN dbo.clientcontact ON dbo.contact.contactid = dbo.clientcontact.contactid
LEFT OUTER JOIN dbo.contact_address ON dbo.contact.contactid = dbo.contact_address.contactid
LEFT OUTER JOIN dbo.address ON dbo.contact_address.addressid = dbo.address.addressid
WHERE
(
contact.dayphone IS NOT NULL
AND contact.dayphone != ''
AND @primaryPhone != ''
AND @primaryPhone IS NOT NULL
AND contact.dayphone LIKE '%' + @primaryPhone + '%'
)
OR
(
contact.fax IS NOT NULL
AND contact.fax != ''
AND @primaryPhone != ''
AND @primaryPhone IS NOT NULL
AND contact.fax LIKE '%' + @primaryPhone + '%'
)
AND clientcontact.contacttypeid = 3 --primary contacts only
UNION
SELECT
address.addressid AS 'optionValue',
('[' + CAST(address.addressid AS NVARCHAR(10)) + '] ' + ISNULL(address.name,'') + ', ' + ISNULL(address1,'') + ', ' + ISNULL(city,'') + ' ' + ISNULL(statecode,'') + ', ' + ISNULL(countrycode,'') + ' ' + ISNULL(postalcode,'')) AS 'optionText'
FROM
dbo.[contact]
LEFT OUTER JOIN dbo.clientcontact ON dbo.contact.contactid = dbo.clientcontact.contactid
LEFT OUTER JOIN dbo.contact_address ON dbo.contact.contactid = dbo.contact_address.contactid
LEFT OUTER JOIN dbo.address ON dbo.contact_address.addressid = dbo.address.addressid
WHERE
@postalCode != ''
AND @postalCode IS NOT NULL
AND address.postalcode LIKE @postalCode + '%'
AND clientcontact.contacttypeid = 3 --primary contacts only
) AS tempTable
查询 #2(搜索)
SELECT tempTable.optionValue, tempTable.optionText FROM (
SELECT
address.addressid AS 'optionValue',
address.name AS 'optionText'
FROM
dbo.address
WHERE
addressid=1
UNION
SELECT
address.addressid AS 'optionValue',
('[' + CAST(address.addressid AS NVARCHAR(10)) + '] ' + ISNULL(address.name,'') + ', ' + ISNULL(address1,'') + ', ' + ISNULL(city,'') + ' ' + ISNULL(statecode,'') + ', ' + ISNULL(countrycode,'') + ' ' + ISNULL(postalcode,'')) AS 'optionText'
FROM
dbo.[address]
LEFT OUTER JOIN dbo.contact_address ON dbo.address.addressid = dbo.contact_address.addressid
LEFT OUTER JOIN dbo.clientcontact ON dbo.contact_address.contactid = dbo.clientcontact.contactid
LEFT OUTER JOIN dbo.client ON dbo.clientcontact.clientid = dbo.client.clientid
LEFT OUTER JOIN dbo.contact ON dbo.contact_address.contactid = dbo.contact.contactid
WHERE
(
client.name IS NOT NULL
AND client.name != ''
AND @companyName != ''
AND @companyName IS NOT NULL
AND client.name LIKE '%' + @companyName + '%'
)
AND
(
(
contact.dayphone IS NOT NULL
AND contact.dayphone != ''
AND @primaryPhone != ''
AND @primaryPhone IS NOT NULL
AND contact.dayphone LIKE '%' + @primaryPhone + '%'
)
OR
(
contact.fax IS NOT NULL
AND contact.fax != ''
AND @primaryPhone != ''
AND @primaryPhone IS NOT NULL
AND contact.fax LIKE '%' + @primaryPhone + '%'
)
)
AND
(
@postalCode != ''
AND @postalCode IS NOT NULL
AND address.postalcode LIKE @postalCode + '%'
)
AND clientcontact.contacttypeid = 3 --primary contacts only
) AS tempTable
【问题讨论】:
-
如果字段为 NULL,由于 LEFT JOIN,是否应该忽略该条件? (或改写,如果该字段为NULL,则从不排除。)
-
是的,如果 ''/NULL 则忽略该条件,但如果它是 ''/NULL 则不要排除该行
-
我的意思是写“是的,如果 ''(或 NULL),则忽略该搜索条件,但如果搜索条件 ''(或 NULL),请不要排除该行”......你是询问数据库中记录中的字段,而不是搜索条件..在这种情况下,如果记录/行字段为''(或NULL),我想排除这些记录......所以我不想要所有您修改后的答案中的那些 OR 条件@Dems。
标签: sql sql-server-2008 tsql search