此查询有什么问题:
WITH volcan AS (SELECT DISTINCT v.numturista
FROM viaje v, sitio s
WHERE v.numsitio = s.numsitio
AND s.tipo = 'Volcan'),
desierto AS (SELECT DISTINCT v.numturista
FROM viaje v, sitio s
WHERE v.numsitio = s.numsitio
AND s.tipo = 'Desierto')
SELECT DISTINCT pais
FROM turista
WHERE numturista IN (volcan INTERSECT desierto);
它不应该等同于以下(因为WITH创建了命名的SELECT查询):
SELECT DISTINCT pais
FROM turista
WHERE numturista IN (
(SELECT DISTINCT v.numturista
FROM viaje v, sitio s
WHERE v.numsitio = s.numsitio
AND s.tipo = 'Volcan')
INTERSECT
(SELECT DISTINCT v.numturista
FROM viaje v, sitio s
WHERE v.numsitio = s.numsitio
AND s.tipo = 'Desierto')
);
它说:
syntax error near INTERSECT.
Postgres版本:psql(PostgreSQL)9.1.9
CREATE TABLE turista (
numturista INTEGER,
nomturista VARCHAR(100),
pais VARCHAR(100),
PRIMARY KEY(numturista)
);
CREATE TABLE sitio (
numsitio INTEGER,
nomsitio VARCHAR(100),
tipo VARCHAR(100),
continente VARCHAR(100),
PRIMARY KEY(numsitio)
);
CREATE TABLE viaje (
numviaje VARCHAR(7),
numturista INTEGER,
numsitio INTEGER,
fechasalida DATE,
fechallegada DATE,
ciudadsalida VARCHAR(100),
PRIMARY KEY(numviaje, numturista, numsitio),
FOREIGN KEY(numsitio) REFERENCES sitio,
FOREIGN KEY(numturista) REFERENCES turista
);
INSERT INTO turista VALUES
(300, 'Carlos', 'Costa Rica')
,(301, 'Pierre', 'Francia')
,(302, 'John', 'Jamaica')
,(303, 'Mario', 'Panama')
,(304, 'Ali', 'Tunez')
,(305, 'Ana', 'Guatemala');
INSERT INTO sitio VALUES
(125, 'Isla Moorea', 'Mar Litoral', 'Oceania')
,(126, 'Bahia Matsushima', 'Mar Litoral', 'Asia')
,(127, 'Irazu', 'Volcan', 'America')
,(128, 'Ngorongoro', 'Volcan', 'Africa')
,(129, 'Valle de la Muerte', 'Desierto', 'America')
,(130, 'Kilimandjar', 'Volcan', 'Africa');
INSERT INTO viaje VALUES
('03-2012', 301, 125, '2013-03-03', '2013-10-03', 'Paris')
,('04-2012', 303, 129, '2013-04-07', '2014-02-07', 'Las Vegas')
,('05-2012', 301, 128, '2013-05-07', '2013-12-07', 'Dar-es-Salam')
,('06-2012', 304, 127, '2013-06-07', '2014-02-07', 'San Jose')
,('07-2012', 302, 128, '2015-04-11', '2014-01-08', 'Mombasa')
,('04-2012', 305, 129, '2013-04-07', '2014-02-07', 'Las Vegas')
,('06-2012', 305, 127, '2013-06-07', '2014-02-07', 'San Jose');
答案 0 :(得分:5)
这相当于:
WITH volcan AS (
SELECT DISTINCT v.numturista
FROM viaje v
JOIN sitio s USING (numsitio)
WHERE s.tipo = 'Volcan'
)
, desierto AS (
SELECT DISTINCT v.numturista
FROM viaje v
JOIN sitio s USING (numsitio)
WHERE s.tipo = 'Desierto'
)
SELECT DISTINCT pais
FROM turista
WHERE numturista IN ((TABLE volcan) INTERSECT (TABLE desierto));
但它可能效率很低......
TABLE tbl
只是SELECT * FROM tbl
的标记快捷方式。
试试这个:
SELECT pais
FROM turista t
WHERE EXISTS (SELECT 1 FROM viaje v JOIN sitio s USING (numsitio)
WHERE v.numturista = t.numturista AND s.tipo = 'Volcan')
AND EXISTS (SELECT 1 FROM viaje v JOIN sitio s USING (numsitio)
WHERE v.numturista = t.numturista AND s.tipo = 'Desierto')
相同,更简单,更快捷。使用EXISTS
,您不需要任何DISTINCT
条款,除非您确实有重复的国家/地区(pais
),我非常怀疑。