使用相同表的数据在其自己的WHERE语句中使用SELECT语句中的表数据

时间:2013-02-17 21:15:40

标签: mysql sql

很抱歉这个令人困惑的标题。可悲的是,案文更令人困惑。

基本上,我有一个SQL脚本,可以将数据从一个表导入另一个表,我试图忽略某些行。

第一个表是每个'事件'记录三行,我只想要其中一个。我想忽略的事件是两个几乎重复,但是一列是0而不是1,以及时间,这可能会有所不同。我给它一个20秒的限制,它仍然匹配。

这是我到目前为止所做的:

INSERT INTO prism_actions (action_time, action_type, player, world, x, y, z, data)
  SELECT FROM_UNIXTIME(`co_blocks`.time), 
    'block-shift', 
    'Piston', 
    CASE WHEN `co_blocks`.wid = 1 THEN 'world' ELSE (CASE WHEN `co_blocks`.wid = 2 THEN 'world_nether' ELSE 'world_the_end' END) END, 
    SUBSTRING_INDEX( `co_blocks`.bcords , '.', 1 ), -- This will get the X coordinate of this action
    SUBSTRING_INDEX(SUBSTRING_INDEX( `co_blocks`.bcords , '.', 2 ),'.', -1), -- Y coordinate
    SUBSTRING_INDEX(SUBSTRING_INDEX( `co_blocks`.bcords , '.', 3 ),'.', -1), -- Z
    CONCAT("{\"block_id\":", `co_blocks`.type, ",\"block_data\":", `co_blocks`.data, "}")
  FROM `co_blocks`
  WHERE `co_blocks`.user LIKE '#piston' 
    AND `co_blocks`.action = 1 
    AND NOT (EXISTS(
      SELECT `id` FROM `co_blocks` WHERE user LIKE '#piston' AND action = 0 AND time < (`co_blocks`.time + 20) AND time > (`co_blocks`.time - 20) AND `co_blocks`.bcords LIKE bcords))
  ORDER BY id ASC;

EXISTS()声明中的WHERE是我试图检查是否有几乎重复的记录。

我的问题是,我正在使用co_blocks。时间检查第一个SELECT列的时间。我不知道它是否会使用第一个SELECT时间或第二个时间。

SELECT `id` 
FROM `co_blocks` 
WHERE user LIKE '#piston' 
AND action = 0 
AND time < (`co_blocks`.time + 20) 
AND time > (`co_blocks`.time - 20) 
AND `co_blocks`.bcords LIKE bcords

它使用相同的表名。 如何使用第一个SELECT数据来检查第二个WHERE中的SELECT

修改 以下是我开始的一些示例数据:

+------+------+------+------------+---------+------------+------+------+--------+------+------+
| id   | cx   | cz   | time       | user    | bcords     | type | data | action | rb   | wid  |
+------+------+------+------------+---------+------------+------+------+--------+------+------+
| 2147 |   22 |   17 | 1361130494 | #piston | 359.67.276 |    3 |    0 |      1 |    0 |    1 |
| 2148 |   22 |   17 | 1361130494 | #piston | 359.67.276 |    3 |    0 |      0 |    0 |    1 |
| 2149 |   22 |   17 | 1361130494 | #piston | 358.67.276 |    3 |    0 |      1 |    0 |    1 |

我想只导入最后一行的数据(bcords不同,action = 1)

编辑2:

我应该就此提供更多背景信息。我正在尝试从一个表co_blocks中获取数据,并将其放入另一个表prism_actions。使用prism_actions的程序仅对此操作使用一行,而使用co_blocks的程序使用3.我只是尝试从co_blocks获取正确的操作并将其放入prism_actions

编辑3:

这是我遇到问题的另一个例子,希望它能让你更容易理解。在我的表中有值,我希望有两个语句将每个表中的信息相互比较。

UPDATE co_pistons
    SET x = (SELECT SUBSTRING_INDEX( bcords , '.', 1 ) FROM `co_pistons` WHERE 
    `co_pistons`.bcords LIKE bcords
    LIMIT 1)
    WHERE NOT isFrom;

在第3行,co_pistons。bcords和bcords指的是同一件事。我希望co_pistons。bcords引用UPDATE的bcords,所以我可以将它们相互比较。

1 个答案:

答案 0 :(得分:0)

作为解决方案,我最终创建了一个单独的表,并添加了我需要使用的所有数据。然后,我可以将子查询中的表数据与主查询的数据进行比较。我不确定这是否太有效,但对于我的脚本,它对我来说很好,因为脚本只运行一次。如果有人有更好的想法,那么这对我有用。

修改

我的问题实际上是我不知道如何使用AS以不同方式命名表。这导致我在查询中使用了两个同名的表,最终让我感到困惑。解决方案是使用昵称命名表:

FROM `co_blocks` as c1
...
SELECT `co_blocks` as c2 WHERE c1.bcords = c2.bcords

我想,之前的解决方案可行,但绝对不是最好的方法。