只过滤掉SQL中某些参数的内容


Only filter out what some parameters have in comon with SQL

我现在已经构建了一个SQL命令,它可以列出带有多个输入的结果。

输入ID为30&31

    $sql ="SELECT ItemRelation.ItemRelTo, ItemRelation.Item, Items.CatID, Items.ItemID,   
    Items.Title, Items.Image, Items.Desc, Items.TimeStamp
    FROM Items
    INNER JOIN ItemRelation 
    ON ItemRelation.ItemRelTo=Items.ItemID
    WHERE ItemRelation.Item  In (30,31) 
    UNION
    SELECT ItemRelation.ItemRelTo, ItemRelation.Item, Items.CatID, Items.ItemID,     
    Items.Title, Items.Image, Items.Desc, Items.TimeStamp
    FROM Items
    INNER JOIN ItemRelation
    ON ItemRelation.Item=Items.ItemID
    WHERE ItemRelation.ItemRelTo In (30,31)";

我的关系表是

Item    ItemRelTo
30      10
31      12
11      12
11      31
30      11

所以我的SQL的结果是Items.ItemID 10,11,12,所以我得到了项11的重复项。

我真正想要的是我的输入(30,31)的共同点,即Items.ItemID=11,而不是重复值,所以只有一个结果

我对此很陌生,所以请解释一下,这样白痴才能理解=)

我显示结果的其余代码是

$result = mysqli_query($con,$sql);
while($row = mysqli_fetch_array($result))
{
    echo '<tr>';
    echo '<td>' . $row['ItemID'] . '</td>';
    echo '<td>' . $row['Item'] . '</td>';
    echo '<td>' . $row['CatID'] . '</td>';
    echo '<td>' . $row['Title'] . '</td>';
    echo '<td><img src="Image/',$row['Image'],'"></td>';
    echo '<td>' . $row['Desc'] . '</td>';
    echo '<td>' . $row['TimeStamp'] . '</td>';
    echo '</tr>'; 
}

这成了我的解决方案。当数据库增长时,可能不是使用Count的最佳方式。感谢迈克帮我到达那里

SELECT   Items.ItemID, GROUP_CONCAT(ItemRelation.ItemRelTo) AS ItemRelTo, Items.CatID,    
Items.Title, Items.Image, Items.Desc, Items.TimeStamp
FROM Items
INNER JOIN ItemRelation 
ON Items.ItemID = ItemRelation.Item
Where ItemRelTo IN (30,31)
Group By ItemID
HAVING COUNT(Items.ItemID) > 1

首先,我不会使用UNION。Yo可以很容易地编写如下SQL:

SELECT
  ItemRelation.ItemRelTo,
  ItemRelation.Item,
  Items.CatID,
  Items.ItemID,   
  Items.Title,
  Items.Image,
  Items.Desc,
  Items.TimeStamp
FROM Items
FULL JOIN ItemRelation
WHERE
  (
    Items.ItemID = ItemRelation.Item
    OR Items.ItemID = ItemRelation.ItemRelTo
  ) AND
  (
    ItemRelation.Item IN(30,31)
    OR ItemRelation.ItemRelTo IN(30,31)
  )

其次,为了只显示DISTINCT id,您需要从select中删除ItemRelation数据,并使用SELECT DISTINCT Items.ItemID,它看起来像这样:

SELECT
  DISTINCT Items.ItemID,
  Items.CatID, 
  Items.Title,
  Items.Image,
  Items.Desc,
  Items.TimeStamp
FROM Items
FULL JOIN ItemRelation
WHERE
  (
    Items.ItemID = ItemRelation.Item
    OR Items.ItemID = ItemRelation.ItemRelTo
  ) AND
  (
    ItemRelation.Item IN(30,31)
    OR ItemRelation.ItemRelTo IN(30,31)
  )

或者,您可以使用GROUP BY Items.ItemID,但随后需要决定如何显示ItemRelation数据的不同值。因为在没有特定聚合的情况下执行GROUP BY会给您带来不可预测的结果。出于演示目的,我可能建议使用GROUP_CONCT

SELECT
  Items.ItemID,
  GROUP_CONCAT(ItemRelation.ItemRelTo) AS ItemsRelatedTo,
  GROUP_CONCAT(ItemRelation.Item) AS ItemRelations,
  Items.CatID, 
  Items.Title,
  Items.Image,
  Items.Desc,
  Items.TimeStamp
FROM Items
FULL JOIN ItemRelation
WHERE
  (
    Items.ItemID = ItemRelation.Item
    OR Items.ItemID = ItemRelation.ItemRelTo
  ) AND
  (
    ItemRelation.Item IN(30,31)
    OR ItemRelation.ItemRelTo IN(30,31)
  )
GROUP BY Items.ItemID

这里真正的问题是你的模式。如果这些关系是多对多且无方向性的(通过您试图查询此数据的方式,似乎是这样),那么在建立关系时,您应该将前向和后向关系都放入关系表中。这允许在任意一个方向上进行查找,并防止您需要在查询中执行相当于重复WHERE子句的操作。

因此,更新你的示例数据,你会有这样的:

Item    ItemRelTo
30      10
10      30
31      12
12      31
11      12
12      11
11      31
31      11
30      11
11      30

这将允许您使用一个大大简化的查询来查找任何具有关联的项目

SELECT
  Items.ItemID,
  GROUP_CONCAT(ItemRelation.ItemRelTo) AS ItemsRelatedTo,
  Items.CatID, 
  Items.Title,
  Items.Image,
  Items.Desc,
  Items.TimeStamp
FROM Items
INNER JOIN ItemRelation
  ON Items.ItemID = ItemRelation.Item
WHERE ItemRelation.ItemRelTo IN(30,31)
GROUP BY Items.ItemID

这成为了我的解决方案。当数据库增长时,可能不是使用Count的最佳方式。感谢迈克帮我到达那里!

SELECT   Items.ItemID, GROUP_CONCAT(ItemRelation.ItemRelTo) AS ItemRelTo,
Items.CatID, Items.Title, Items.Image, Items.Desc, Items.TimeStamp
FROM Items
INNER JOIN ItemRelation 
ON Items.ItemID = ItemRelation.Item
Where ItemRelTo IN (30,31)
Group By ItemID
HAVING COUNT(Items.ItemID) > 1