具有“动态”where子句的SQL语句

4

可能是重复问题:
如何构建一个SQL语句,使用可能不存在于表中的ID?

大家好,我试图构建一个带有一些未知变量的SQL语句。 我想从表dbo.pmd中选择省份、地区、公社和村庄。 由于只存储了ID,所以我需要从值表中读取名称。 对于省份和地区来说,这不是问题,因为它们将始终填充在表dbo.pmd中。无论如何,公社和村庄不是强制性的,因此可能没有填充。 如果我比较dbo.pmd和dbo.vhcs(公社)以及dbo.pmd和dbo.vhv(村庄)之间的ID,并且dbo.pmd表中没有存储任何值,那么就会出现问题。

表格如下:

表:dbo.pmd
字段:province, district, commune, village(存储值为ID号码)

表:dbo.vhp
字段:country_id, province_id, province_en(省份名称)

表格: dbo.vhd
字段: province_id, district_id, district_en (区名称)

表格: dbo.vhc2
字段: district_id, commune_id, commune_en (社区名称)

表格: dbo.vhv
字段: commune_id, village_id, village_en (村庄名称)

我的当前语句如下:

SELECT pmd.patient_code, pmd.last_name, pmd.first_name, pmd.age, pmd.sex, pmd.province, pmd.district, pmd.commune, pmd.village 
FROM dbo.pmd AS pmd
INNER JOIN dbo.vhp AS vhp 
ON pmd.province = vhp.province_id
INNER JOIN dbo.vhd AS vhd
ON pmd.district = vhd.district_id 
INNER JOIN dbo.vhc2 AS vhc2
ON (pmd.commune is NULL OR (pmd.commune = vhc2.commune_id)) 
INNER JOIN dbo.vhv AS vhv
ON (pmd.village is NULL OR (pmd.village = vhv.village_id))
ORDER BY pmd.last_name

我在数据库中有两个条目。一个带有commune_id和village_id = NULL,另一个带有commune_id和village_id =某个ID号码。

我停止了这个语句的执行大约2分钟,结果显示8273612行,所有行的值都相同,只显示commund_id和village_id等于NULL的条目。

我正在使用Microsoft SQL Server 2008。


@OMG Ponies:这个案例更加复杂,所以这篇帖子中的结果不起作用。 - Daniel
2个回答

2
    INNER JOIN dbo.vhc2 AS vhc2
ON (pmd.commune is NULL OR (pmd.commune = vhc2.commune_id)) 

在这里,您无意中执行了类似笛卡尔乘积的操作。在 pmd.commune 为 NULL 的行上,pmd.commune IS NULL 对于 vhc2 中的每一行都会评估为真,导致 vhc2 的每一行都会与该 pmd 行连接。
这次您的情况与之前描述的有些不同,所以那里提供的解决方案对您当前的情况没有帮助。
您想要进行某种外连接的变化,例如:对于 vhc2vhv

LEFT OUTER JOIN dbo.vhc2 AS vhc2
ON  pmd.commune = vhc2.commune_id

1

在连接操作中,这两个is null检查导致了问题。我认为你要使用左连接。

SELECT pmd.patient_code, pmd.last_name, pmd.first_name, pmd.age, pmd.sex, pmd.province, pmd.district, pmd.commune, pmd.village 
FROM dbo.pmd AS pmd
    INNER JOIN dbo.vhp AS vhp 
        ON pmd.province = vhp.province_id
    INNER JOIN dbo.vhd AS vhd
        ON pmd.district = vhd.district_id 
    LEFT JOIN dbo.vhc2 AS vhc2
        ON pmd.commune = vhc2.commune_id
    LEFT JOIN dbo.vhv AS vhv
        ON pmd.village = vhv.village_id
ORDER BY pmd.last_name

附注:您可能需要重新审视表命名 - 非常难以理解数据库设计。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接