拥有购买的所有元素

时间:2017-12-12 22:48:58

标签: mysql sql select having

我遇到了SELECT的问题。我在MySQL工作。

我想得到" consumidor"购买产品的电子邮件(" Produto"),包括所有" Elemento"。

我这样做了:

SELECT C.email
FROM Consumidor C, composto composto, compra compra
WHERE C.numero = compra.consumidor

HAVING COUNT(DISTINCT composto.elemento) = ( SELECT COUNT(*)
                                             FROM Elemento E)

但它没有用。我只得到了一个结果,我知道还有更多结果。我知道WHEREHAVING之间缺少某些内容。

TABLES

Create table  Consumidor  (
    numero  int(9),
    email   varchar(30) not null,
    sexo    char(1) not null,
    nascimento  date    not null,
    constraint Consumidor_sexo_RI001     check (sexo in ('F','M')),
    constraint Consumidor_unique_RI002  unique(email),
    constraint pk_Consumidor     primary key (numero)
);
Create table  Elemento  (
    codigo  char(3),
    nome    varchar(25) not null,
    pegadaEcologica int(2) not null,
    saude   int(2) not null,
    constraint pk_Elemento   primary key (codigo)
);
Create table  Produto  (
    codigo  int(6),
    marca   int(7),
    nome    varchar(50) not null,
    tipo    char(10),
    comercioJusto   char(1),
    constraint Produto_tipo_RI004   check (tipo in ('alimentac','lar','jardim','automov','viagem','electrodom')),
    constraint Produto_comercioJusto_RI005   check (comercioJusto in ('A','B','C','D')),
    constraint fk_Produto_marca  foreign key (marca) references Marca(numero) on delete cascade,
    constraint pk_Produto    primary key (codigo,marca)
);
Create table  compra  (
    produto int(6),
    prodMarca   int(7),
    consumidor  int(9),
    quantidade  decimal(10,3)   not null,
    constraint compra_quantidade_RI006  check (quantidade>0),
    constraint fk_compra_produto     foreign key (produto,prodMarca) references Produto(codigo,marca) on delete cascade,
    constraint fk_compra_consumidor  foreign key (consumidor) references Consumidor(numero) on delete cascade,
    constraint pk_compra     primary key (produto,prodMarca,consumidor)
);
Create table  composto  (
    produto int(6),
    prodMarca   int(7),
    elemento    char(3),
    percentagem decimal(4,1)    not null,
    constraint composto_percentagem_RI007   check (percentagem>0 and percentagem<=100),
    constraint fk_composto_produto   foreign key (produto,prodMarca) references Produto(codigo,marca) on delete cascade,
    constraint fk_composto_elemento  foreign key (elemento) references Elemento(codigo) on delete cascade,
    constraint pk_composto   primary key (produto,prodMarca,elemento)
);

2 个答案:

答案 0 :(得分:1)

具有

您对HAVING功能的使用不正确。您所说的elemento(产品详细信息)的数量应该等于Composto(产品到产品详细信息表)的数量。

您只获得1行的原因是,您从“商品详细信息”表格中加入了Count或行数,以及您的商品数量#39已经找回了。

试试这个:

SELECT COUNT(*) FROM Elemento E

您将看到只返回1个单一金额(您拥有的实际产品详细信息的数量)。

现在尝试:

SELECT COUNT(DISTINCT composto.elemento) FROM composto

你会看到数字匹配。

您所做的只是计算物品数量。这显然不是您正在寻找的内容,因为这不是优化结果的正确方法。

关系联接

此外,您还没有正确加入表格。 MySQL是一个&#39; relational database&#39;这意味着你需要专门定义关系&#39;你的对象(表)之间。

首先,您需要更新查询以更正联接:

 SELECT Customer.email, ProductDetails.nome
 FROM Consumidor Customer

    -- Joins the Consumidor (consumer) table to the Compra (sales) table
    INNER JOIN compra Sales
        ON Customer.numero = Sales.consumidor

    -- Joins the sales to the Produto (products) table
    INNER JOIN Producto Product
        ON Sales.produto = Product.codigo

    -- Joins the composto (Composite Key) table to the elemento (Product Details) table
    INNER JOIN composto
        ON composto.produto = Product.codigo

    -- Now get the Product details
    INNER JOIN elemento ProductDetails
        ON composto.elemento = ProductDetails.codigo

现在,您的联接应该正常运行,您将获得人员(客户),他们购买的产品(compra)以及有关产品的详细信息。

获取结果

我假设您想要的是Produto(产品)的子集。如果这是正确的,那么您需要做的是使用predicates条款正确定义'WHERE'

SELECT Customer.email, ProductDetails.nome
FROM Consumidor Customer

    -- Joins the Consumidor (consumer) table to the Compra (sales) table
    INNER JOIN compra Sales
        ON Customer.numero = Sales.consumidor

    -- Joins the sales to the Produto (products) table
    INNER JOIN Producto Product
        ON Sales.produto = Product.codigo

    -- Joins the composto (Composite Key) table to the elemento (Product Details) table
    INNER JOIN composto
        ON composto.produto = Product.codigo

    -- Now get the Product details
    INNER JOIN elemento ProductDetails
        ON composto.elemento = ProductDetails.codigo
-- You can search for whatever matches your criteria here    
WHERE Customer.nome = 'Möoz' -- Finds all products that user 'Möoz' has bought

您还可以在&#39; WHERE&#39;中添加或删除谓词。用于优化搜索的子句:

WHERE ProductDetails.pegadaEcologica = 'Low' --searches for a 'low ecological footprint' product only

WHERE ProductDetails.nome = 'Black Show' -- Searches for black shoes in the name of the product

WHERE ProductDetails.codigo = 35 -- Searches for the item with the ID of 35

...

答案 1 :(得分:-1)

我无法测试它,因此您可能会遇到一些语法错误。尝试一下,看看它是否有效:

-- Get e-mail of consumer who bought products which include all elements
SELECT cdr.email
FROM compra cmp -- Get all purchases
INNER JOIN consumidor cdr ON cmp.consumidor = cdr.numero -- Get consumer info
WHERE (cmp.produto, cmp.prodMarca) IN ( -- Only look at purchases which included products that included all elements
    SELECT pto.codigo, pto.marca
    FROM produto pto -- Get all products
    INNER JOIN composto cpt ON pto.codigo = cpt.produto AND cpt.prodMarca = pto.marca -- Get all elements defined for each product
    HAVING COUNT(*) = (SELECT COUNT(*) FROM elemento) -- Only return products that have all elements
    GROUP BY pto.codigo, pto.marca
);

此外,您可能希望保留相同或类似的列名FOR PK / FK引用。这使您更容易阅读和理解您的SQL /架构。如果有效,请告诉我。