在一个条件下查询一对多的实际情况

时间:2015-10-20 14:37:25

标签: mysql sql

我有一个包含三个表的数据库

  • 产品
  • FIELDNAMES
  • 字段值

产品:

  • ID
  • 名称

的字段名:

  • 填充NameID
  • DisplayName的

字段值

  • 的ProductID
  • 填充NameID
  • fieldValue方法

我正在尝试将所有产品的字段中的日期命名为' start'是在今天早些时候和现场的日期结束'是在今天晚些时候。

我目前的解决方案:

SELECT ID
FROM Product
WHERE  (SELECT FieldValue 
        FROM FieldValues
        WHERE NameID = ( SELECT NameID 
                        FROM Fieldnames
                        WHERE DisplayName = 'start')) < today
AND (SELECT FieldValue 
        FROM FieldValues
        WHERE NameID = ( SELECT NameID 
                        FROM Fieldnames
                        WHERE DisplayName = 'end')) > today

今天用c#代码填写。 但这并没有返回所需的输出。我错过了什么?

3 个答案:

答案 0 :(得分:2)

我认为这就是你要做的事。

SELECT p.ID
FROM Product p
JOIN FieldValues fv on p.id = fv.productid
JOIN Fieldnames fn on fn.nameid = fv.nameid
WHERE 
    (DisplayName = 'start' and fv.FieldValue < today)
OR (DisplayName = 'end' and fv.FieldValue > today)

答案 1 :(得分:2)

您需要将Fieldvalues.ProductID链接回Product.ID。

SELECT ID 
FROM Products p 
WHERE (SELECT fv.FieldValue 
       FROM FieldValues fv JOIN Fieldnames fn ON fv.NameID = fn.NameID
       WHERE fv.ProductID = p.ID AND fn.DisplayName = 'start') < today   
  AND (SELECT fv.FieldValue 
       FROM FieldValues fv JOIN Fieldnames fn ON fv.NameID = fn.NameID
       WHERE fv.ProductID = p.ID AND fn.DisplayName = 'end') > today 

答案 2 :(得分:2)

尝试......

SELECT ID
FROM Products, FieldNames, FieldValues
WHERE FieldValues.ProductID = Products.ID AND
      FieldValues.NameID = FieldNames.NameID AND
      ( ( DisplayName = "start" AND FieldValue < today ) OR
        ( DisplayName = "end" AND FieldValue > today ) );

如果没有测试数据,我无法对此进行测试,幸运的是,有足够的时间让我这样做。将来,如果你发布用于创建表格的脚本并用测试数据填充它们,我们可以检查我们对任何错误的答案。

首先,我将解释我的答案背后的原因,之后我将列出我用来测试的脚本。

我开始 -

SELECT *
FROM Products, FieldNames, FieldValues
WHERE FieldValues.ProductID = Products.ID AND
      FieldValues.NameID = FieldNames.NameID

我在这里使用SELECT *而不是SELECT ID,所以我可以检查数据以确定我是否获得了准确的结果。无论哪种方式都可以。

我使用了FROM Products, FieldNames, FieldValues而不仅仅是FROM Products,因为我们正在引用WHERE子句中的所有三个表,即使我们只返回了ID。我只用FROM Products试了一下 - 它抱怨了(并没有工作)。

我添加了 -

WHERE FieldValues.ProductID = Products.ID AND
      FieldValues.NameID = FieldNames.NameID

加入表,由于FieldName和FieldValue位于不同的表中,这是必要的。我还包括对产品的加入,以防您希望从ID返回任何其他字段。如果您只想返回ID,那么您应该将前四行更改为 -

SELECT *
FROM FieldNames, FieldValues
WHERE FieldValues.NameID = FieldNames.NameID

无论哪种方式,要将搜索细化为仅添加的有效结果 -

      ( ( DisplayName = "start" AND FieldValue < today ) OR
        ( DisplayName = "end" AND FieldValue > today ) );

最外面的括号是必要的,否则OR可能会与连接条款混淆。即使它不是,它也是隔离我们超出范围的论点的好方法。

同样,最里面的括号有助于保留(start,&lt;)和(end,&gt;)条件。

我通过用45代替value来测试最终陈述,la -

SELECT ID
FROM Products, FieldNames, FieldValues
WHERE FieldValues.ProductID = Products.ID AND
      FieldValues.NameID = FieldNames.NameID AND
      ( ( DisplayName = "start" AND FieldValue < 45 ) OR
        ( DisplayName = "end" AND FieldValue > 45 ) );

结果符合要求。

以下是我用来创建和填充表格的脚本......

CREATE DATABASE Products20151020;

USE Products20151020;

CREATE TABLE Products
(
    ID      INT              NOT NULL    AUTO_INCREMENT,
    Name    VARCHAR( 50 )    NOT NULL,
    PRIMARY KEY ( ID )
);

CREATE TABLE FieldNames
(
    NameID         INT              NOT NULL    AUTO_INCREMENT,
    DisplayName    VARCHAR( 50 )    NOT NULL,
    PRIMARY KEY ( NameID )
);

CREATE TABLE FieldValues
(
    fldID         INT    NOT NULL    AUTO_INCREMENT,
    ProductID     INT    NOT NULL,
    NameID        INT    NOT NULL,
    FieldValue    INT    NOT NULL,
    PRIMARY KEY ( fldID ),
    FOREIGN KEY ( ProductID )    REFERENCES Products( ID ),
    FOREIGN KEY ( NameID )       REFERENCES FieldNames( NameID )
);

INSERT INTO Products
SET Name = "Name 001";

INSERT INTO Products
SET Name = "Name 002";

INSERT INTO Products
SET Name = "Name 003";

INSERT INTO Products
SET Name = "Name 004";

INSERT INTO Products
SET Name = "Name 005";

INSERT INTO Products
SET Name = "Name 006";

INSERT INTO Products
SET Name = "Name 007";

INSERT INTO Products
SET Name = "Name 008";

INSERT INTO Products
SET Name = "Name 009";

INSERT INTO Products
SET Name = "Name 010";

INSERT INTO FieldNames
SET DisplayName = "start";

INSERT INTO FieldNames
SET DisplayName = "end";

INSERT INTO FieldValues
SET ProductID  = 1,
    NameID     = 1,
    FieldValue = 26;

INSERT INTO FieldValues
SET ProductID  = 5,
    NameID     = 1,
    FieldValue = 46;

INSERT INTO FieldValues
SET ProductID  = 3,
    NameID     = 1,
    FieldValue = 45;

INSERT INTO FieldValues
SET ProductID  = 7,
    NameID     = 1,
    FieldValue = 44;

INSERT INTO FieldValues
SET ProductID  = 10,
    NameID     = 1,
    FieldValue = 100;

INSERT INTO FieldValues
SET ProductID  = 8,
    NameID     = 1,
    FieldValue = 10;

INSERT INTO FieldValues
SET ProductID  = 9,
    NameID     = 1,
    FieldValue = 32;

INSERT INTO FieldValues
SET ProductID  = 2,
    NameID     = 1,
    FieldValue = 99;

INSERT INTO FieldValues
SET ProductID  = 10,
    NameID     = 2,
    FieldValue = 26;

INSERT INTO FieldValues
SET ProductID  = 9,
    NameID     = 2,
    FieldValue = 46;

INSERT INTO FieldValues
SET ProductID  = 7,
    NameID     = 2,
    FieldValue = 45;

INSERT INTO FieldValues
SET ProductID  = 6,
    NameID     = 2,
    FieldValue = 44;

INSERT INTO FieldValues
SET ProductID  = 4,
    NameID     = 2,
    FieldValue = 100;

INSERT INTO FieldValues
SET ProductID  = 3,
    NameID     = 2,
    FieldValue = 10;

INSERT INTO FieldValues
SET ProductID  = 1,
    NameID     = 2,
    FieldValue = 32;

INSERT INTO FieldValues
SET ProductID  = 2,
    NameID     = 2,
    FieldValue = 99;

如果有任何问题或一般性评论,请随时发表评论。