好的,我们说我有一张叫做房间的桌子:
它只有一列:ID
我还有另一个名为items_in_rooms的表,其中包含列:
roomId,itemName,itemColor
每当插入房间记录时,还会在链接到行记录的items_in_rooms中插入一堆记录,指定该房间中的项目。
问题在于,当房间记录及其项目时,我需要首先验证具有这些确切项目的房间是否已经存在。 怎么办呢?
当然,一种方法是首先获取所有房间记录及其所有项目,然后查看它们,直到验证数据库中还没有完全复制,然后插入(&#) 39;独特。 但这对我来说听起来有点无效,特别是随着表格变得非常大,所以我希望有一种方法让MYSQL进行检查。
我提出的一种方法是做这样的事情:
SELECT roomId FROM(
SELECT rooms.id roomId, GROUP_CONCAT(
CONCAT_WS(',',itemName,itemColor) ORDER BY itemName,itemColor SEPARATOR '/'
) roomContents
FROM items_in_rooms
JOIN rooms ON roomId=rooms.id
WHERE snapshotDate='$dateString'
GROUP BY roomId
) concatenatedRoomContents
WHERE roomContents='bed,white/carpet,red/chair,brown'
本质上,这将使MYSQL将每个房间连接成一个字符串,然后将它们与"输入字符串"进行比较。在WHERE子句中。显然,输入字符串的排序方式与MYSQL在连接(itemName,itemColor)之前对行排序的方式相同。
虽然这很有效但感觉很脏。此外,当我添加十进制字段时,它最初会引起一些问题,因为MYSQL在字符串化时始终包含每个十进制数字,因此例如1可能是" 1.000" 而我默认使用的PHP将其字符串化为" 1"。我使用number_format()解决了这个问题,使其包含了正确的十进制数字。 现在我已经注意到我再次在桌子上找到了一些副本,所以我需要找到其他一些问题,但我只是想知道是否有更聪明的方法?
答案 0 :(得分:0)
这是如何做到的。如果存在这样的房间,则以下查询返回房间的id(它正好具有这些项目,不多也不少)。
SELECT roomId FROM (
SELECT roomId,count(*) numMatchedItems
FROM items_in_rooms WHERE (itemName,itemColor)
IN (('bed','white'),('carpet','red'),('chair','brown'))
GROUP BY roomId
) matches
WHERE numMatchedItems=3
谢谢,CBroe。