我有不同国家的项目数据。每个项目都有一个devlevel
,一个sector
和一个subsector
,例如(简化):
pid | sector | subsector | devlevel
------+------------------------------------------+----------------------+----------
612 | Transport | Airports & Logistics | EM
1473 | Information & Communication Technologies | Broadband | RoW
1424 | Other | Other | RoW
1476 | Transport | Urban Highways | RoW
1443 | Water | Water Supply | EM
根据这三个特征的组合,每个项目都有一定的efficiency
。目前,我已经构建了这样的查找表:
sector | subsector | devlevel | efficiency
-----------+--------------------+----------+------------
Transport | (null) | EM | 16000
Transport | (null) | RoW | 9600
Water | (null) | EM | 16000
Water | (null) | RoW | 9600
Energy | Generation — Hydro | EM | 16000
Energy | Generation — Hydro | RoW | 9600
Energy | (null) | EM | 11200
Energy | (null) | RoW | 6720
(null) | (null) | EM | 8000
(null) | (null) | RoW | 8000
逻辑是:如果项目有sector
和subsector
匹配,请使用与其efficiency
对应的devlevel
。如果它有sector
匹配而不是subsector
,请使用对应于efficiency
和devlevel
subsector
的NULL
。如果sector
根本没有匹配,请使用efficiency
以及sector
的subsector
和NULL
值。
我一直在努力实现一个查询相关efficiency
的查询。我的最新尝试如下。它尝试在初始子查询中基于sector
缩小可能的查找值,然后在后续(父)子查询中基于subsector
进一步缩小它们,然后使用devlevel
上的匹配将精简查找表连接到项目数据。但我收到此错误消息:
ERROR: invalid reference to FROM-clause entry for table "p"
LINE 26: SELECT 1 FROM devlookup d1 WHERE p.sector = ...
^
HINT: There is an entry for table "p", but it cannot be referenced from this part of the query.
SQL state: 42P01
Character: 4079
指针将非常感激。
查询:
WITH devlookup (id, sector, subsector, devlevel, efficiency)
AS (VALUES
(1, 'Transport', NULL, 'EM', 16000),
(2, 'Transport', NULL, 'RoW', 9600),
(3, 'Water', NULL, 'EM', 16000),
(4, 'Water', NULL, 'RoW', 9600),
(5, 'Energy', 'Generation — Hydro', 'EM', 16000),
(6, 'Energy', 'Generation — Hydro', 'RoW', 9600),
(7, 'Energy', NULL, 'EM', 11200),
(8, 'Energy', NULL, 'RoW', 6720),
(9, NULL, NULL, 'EM', 8000),
(10, NULL, NULL, 'RoW', 8000)
),
EMcountries AS (VALUES ('United Arab Emirates'), ('Afghanistan'), ('Antigua and Barbuda'), ('Anguilla'), ('Armenia'), ('Netherlands Antilles'), ('Angola'), ('Antarctica'), ('Argentina'), ('American Samoa'), ('Aruba'), ('Azerbaijan'), ('Barbados'), ('Bangladesh'), ('Burkina'), ('Bahrain'), ('Burundi'), ('Benin'), ('Brunei'), ('Bolivia'), ('Brazil'), ('Bahamas'), ('Bhutan'), ('Bouvet Island'), ('Botswana'), ('Belarus'), ('Belize'), ('Cocos (Keeling) Islands'), ('Congo {Democratic Rep}'), ('Central African Republic'), ('Congo'), ('Ivory Coast'), ('Cook Islands'), ('Chile'), ('Cameroon'), ('China'), ('Colombia'), ('Costa Rica'), ('Cuba'), ('Cape Verde'), ('Christmas Island'), ('Djibouti'), ('Dominica'), ('Dominican Republic'), ('Algeria'), ('Ecuador'), ('Egypt'), ('Western Sahara'), ('Eritrea'), ('Ethiopia'), ('Fiji'), ('Falkland Islands (Malvinas)'), ('Micronesia), (Federated States of'), ('Gabon'), ('Grenada'), ('Georgia'), ('French Guiana'), ('Ghana'), ('Gambia'), ('Guinea'), ('Guadeloupe'), ('Equatorial Guinea'), ('South Georgia and the South Sandwich Islands'), ('Guatemala'), ('Guam'), ('Guinea-Bissau'), ('Guyana'), ('Heard Island and McDonald Islands'), ('Honduras'), ('Haiti'), ('Indonesia'), ('India'), ('British Indian Ocean Territory'), ('Iraq'), ('Iran'), ('Jamaica'), ('Jordan'), ('Kenya'), ('Kyrgyzstan'), ('Cambodia'), ('Kiribati'), ('Comoros'), ('Saint Kitts and Nevis'), ('Korea), (Democratic People''s Republic of'), ('Kuwait'), ('Cayman Islands'), ('Kazakhstan'), ('Lao People''s Democratic Republic'), ('Lebanon'), ('St Lucia'), ('Sri Lanka'), ('Liberia'), ('Lesotho'), ('Libya'), ('Morocco'), ('Madagascar'), ('Marshall Islands'), ('Mali'), ('Myanmar), ({Burma}'), ('Mongolia'), ('Northern Mariana Islands'), ('Martinique'), ('Mauritania'), ('Montserrat'), ('Mauritius'), ('Maldives'), ('Malawi'), ('Mexico'), ('Malaysia'), ('Mozambique'), ('Namibia'), ('New Caledonia'), ('Niger'), ('Norfolk Island'), ('Nigeria'), ('Nicaragua'), ('Nepal'), ('Nauru'), ('Niue'), ('Oman'), ('Panama'), ('Peru'), ('French Polynesia'), ('Papua New Guinea'), ('Philippines'), ('Pakistan'), ('Pitcairn Islands'), ('Puerto Rico'), ('Palestinian Territory'), ('Palau'), ('Paraguay'), ('Qatar'), ('Reunion'), ('Rwanda'), ('Saudi Arabia'), ('Solomon Islands'), ('Seychelles'), ('South Sudan'), ('Sudan'), ('Saint Helena'), ('Sierra Leone'), ('Senegal'), ('Somalia'), ('Suriname'), ('Sao Tome & Principe'), ('El Salvador'), ('Syria'), ('Swaziland'), ('Turks and Caicos Islands'), ('Chad'), ('French Southern Territories'), ('Togo'), ('Thailand'), ('Tajikistan'), ('Tokelau'), ('Turkmenistan'), ('Tunisia'), ('Tonga'), ('Timor-Leste'), ('Trinidad & Tobago'), ('Tuvalu'), ('Tanzania'), ('Ukraine'), ('Uganda'), ('United States Minor Outlying Islands'), ('Uruguay'), ('Uzbekistan'), ('Saint Vincent and the Grenadines'), ('Venezuela'), ('Virgin Islands), (British'), ('Virgin Islands), (U.S.'), ('Vietnam'), ('Vanuatu'), ('Wallis and Futuna'), ('Samoa'), ('Yemen'), ('Mayotte'), ('South Africa'), ('Zambia'), ('Zimbabwe'), ('Saint Barthelemy'), ('Saint Martin')),
projectinfo AS (
SELECT p.pid, p.country, p.projectname, p.sector, p.subsector,
(CASE WHEN p.country IN (SELECT * FROM EMcountries) THEN 'EM' ELSE 'RoW' END) AS devlevel
FROM exp_projects p
)
SELECT p.pid, p.country, p.projectname, p.sector, p.subsector, p.devlevel, d.sector devsector, d.subsector devsubsector, d.efficiency
FROM projectinfo p
LEFT OUTER JOIN (
SELECT * FROM (
SELECT * FROM devlookup WHERE id IN (
CASE WHEN EXISTS (
SELECT 1 FROM devlookup d1 WHERE p.sector = d1.sector
)
THEN (SELECT id FROM devlookup d1 WHERE d1.sector = p.sector)
ELSE (SELECT id FROM devlookup d1 WHERE d1.sector IS NULL)
END
)
) AS devlookup_matching_sector
WHERE id IN (
CASE WHEN EXISTS (
SELECT 1 FROM devlookup_matching_sector dms WHERE dms.subsector = p.subsector
)
THEN (SELECT id FROM devlookup_matching_sector dms WHERE dms.subsector = p.subsector)
ELSE (SELECT id FROM devlookup_matching_sector dms WHERE dms.subsector IS NULL)
END
)
) devlookup_matching_sector_subsector
ON (devlookup_matching_sector_subsector.devlevel = p.devlevel)
WHERE p.country IN ('Australia', 'Afghanistan', 'Brazil')
ORDER BY pid ASC;
我没有在这里修改你的主要查询,只是演示了一种机制来选择最适用的特定效率:
SELECT
p.*,
COALESCE(mostspecific.efficiency, midspecific.efficiency, leastspecific.efficiency) as best_e
FROM
Project p
LEFT JOIN
Efficiency mostspecific
ON
p.devlevel = mostspecific.devlevel AND
p.sector = mostspecific.sector AND
p.subsector = mostspecific.subsector
LEFT JOIN
Efficiency midspecific
ON
p.devlevel = midspecific.devlevel AND
p.sector = midspecific.sector AND
midspecific.subsector IS NULL
LEFT JOIN
Efficiency leastspecific
ON
p.devlevel = leastspecific.devlevel AND
leastspecific.sector IS NULL AND
leastspecific.subsector IS NULL
逻辑起作用是因为JOIN会在匹配方面有所不同。最小的特定应该始终匹配,med应该多次,最多,几次。 Coalesce从左到右选择第一个非空值,因此通过将效率按最可能失败的顺序(为空)设置为最小,意味着应选择最相关的特定值。