0

我现在已经构建了一个 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,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
4

2 回答 2

0

首先,我不会使用 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 和 useSELECT DISTINCT Items.ItemID中删除 ItemRelation 数据,如下所示:

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_CONCAT

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
于 2013-07-30T22:19:17.587 回答
0

这成了我的解决方案。当数据库增长时,可能不是他使用 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
于 2013-07-31T23:39:35.857 回答