Php 使用SQL只过滤掉comon中的某些参数
我现在已经构建了一个SQL命令,它可以列出带有多个输入的结果 它看起来是这样的,输入ID为30和31Php 使用SQL只过滤掉comon中的某些参数,php,mysql,Php,Mysql,我现在已经构建了一个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
$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.itemid10,11,11,12,所以我得到了item 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>';
}
首先,我不会使用工会。您可以按照如下方式轻松编写此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)
)
其次,为了只显示不同的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_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
这成了我的解决办法。可能不是在数据库增长时使用计数的最佳方法。谢谢迈克帮我到达那里
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
回答得好!我的第一个想法是在关系表中添加两种方式,但是当我开始添加很多行时,似乎有很多额外的数据。嗨!我只是修改了关系表中的数据,并使用了您上次的SQL建议。但这给了我比11更多的结果。结果:(ItemID-itemsreletto)(10-30)(11-30,31)(12-31)是正确的。这些是与30或31相关的项目。您正在寻找与30和31都相关的项目吗?是的,所以我只得到项目ID 11,这是30和31的共同点。
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