0

这是我的意思的具体例子。我定义了下表:

CREATE TABLE pets (
    id INTEGER UNSIGNED NOT NULL,
    name VARCHAR(20) NOT NULL,
    breed VARCHAR(20) NOT NULL,
    color VARCHAR(20) NOT NULL,
    weight INTEGER UNSIGNED NOT NULL,
    PRIMARY KEY (id)
);

我将如何编写 SQL 查询来查找包含与可卡犬颜色相同的宠物的品种?因此,如果数据库中的所有可卡犬都是黑色或白色,我需要找到至少有 1 只黑色宠物和 1 只黄色宠物的所有不同品种。我已经被这个问题难住了一段时间,并且无法在网上找到类似的答案,所以这里的任何帮助将不胜感激。

4

4 回答 4

2

与往常一样,将实际的 RDBMS 保密会使事情变得更加困难。

对于支持 CTE 的数据库(PostgreSQL、Oracle、SQL Server、..)

CTE:

WITH colors AS (
    SELECT DISTINCT color
    FROM   pets
    WHERE  breed = 'cocker spaniels'
    )
SELECT p.breed
FROM   colors c
JOIN   pets   p USING (color)
GROUP  BY p.breed
HAVING count(DISTINCT p.color) = (SELECT count(*) FROM color);

解释

  1. 在 CTE 中获取一组不同颜色的可卡犬color
  2. 加入所有相同颜色的宠物,按品种分组宠物
  3. 在该HAVING子句中验证不同颜色的数量是否与可卡犬进入的颜色数量相匹配。

尔格:由此产生的宠物(包括可卡犬)具有可卡犬的所有颜色 - 甚至可能更多。

这是关系划分的一个特例。我们最近在这个相关问题下收集了一整套查询。


对于 MySQL

SELECT p.breed
FROM (
   SELECT DISTINCT color
   FROM   pets
   WHERE  breed = 'cocker spaniels'
   ) c
JOIN   pets p USING (color)
GROUP  BY p.breed
HAVING count(DISTINCT p.color) = (
   SELECT count(DISTINCT color)
   FROM   pets
   WHERE  breed = 'cocker spaniels'
   );

-> sqlfiddle

于 2012-10-17T01:29:23.597 回答
0

如果我理解正确,您不想要全白或全黑的品种。你只想要白色和黑色的品种(可卡犬的不同颜色)。基于此,这就是我想出的(尽管它可能不是最有效的)。

DECLARE @pets TABLE(
  id INTEGER NOT NULL,
  name VARCHAR(20) NOT NULL,
  breed VARCHAR(20) NOT NULL,
  color VARCHAR(20) NOT NULL,
  weight INTEGER NOT NULL,
  PRIMARY KEY (id)
);

INSERT INTO @pets VALUES (1, 'jeff', 'breed1', 'black', 20)
INSERT INTO @pets VALUES (2, 'larry', 'breed1', 'white', 20)
INSERT INTO @pets VALUES (3, 'bob', 'breed2', 'black', 30)
INSERT INTO @pets VALUES (4, 'kevin', 'breed3', 'black', 30)
INSERT INTO @pets VALUES (5, 'jerry', 'breed3', 'white', 30)

DECLARE @breed VARCHAR(50)
SET @breed = 'breed1'
;WITH cte (color) AS (SELECT DISTINCT color FROM @pets WHERE breed = @breed)
SELECT breed, COUNT(id) FROM @pets WHERE color IN (SELECT color FROM cte)
  AND breed != @breed
GROUP BY breed
HAVING COUNT(id) >= (SELECT COUNT(*) FROM cte)

Result: breed3

如果您使用的 SQL 版本不支持 CTE,则可以使用临时表或表变量来保存您需要在其他品种中寻找的颜色。希望这会有所帮助!

于 2012-10-17T01:25:53.703 回答
0
--parameter
DECLARE @breed varchar(20)
SET @breed = 'Cocker Spaniel' 

--count distinct colors for param
DECLARE @colors int
SELECT @colors = COUNT(DISTINCT color) FROM pets WHERE breed = @breed 

--match param breed with others based on color
--return only breed with matching count of distinct colors
SELECT otherBreeds.breed
FROM
    (SELECT DISTINCT breed, color FROM pets WHERE breed = @breed) AS thisBreed
    LEFT OUTER JOIN (SELECT DISTINCT breed, color FROM pets WHERE breed <> @breed) AS otherBreeds
    ON thisBreed.color = otherBreeds.color
GROUP BY otherBreeds.breed
HAVING COUNT(DISTINCT otherBreeds.color) = @colors
于 2012-10-17T01:46:09.173 回答
0
SELECT  DISTINCT breeds  FROM pets 
WHERE color in (SELECT color FROM pets where name='cocker spaniels')
于 2012-10-17T01:11:30.450 回答