#1222 - 使用的SELECT语句具有不同的列数

时间:2010-10-15 22:50:23

标签: sql mysql mysql-error-1222

为什么我得到#1222-使用的SELECT语句具有不同的列数 ?我正在尝试从这些用户朋友和他自己那里加载墙上的帖子。

SELECT u.id AS pid, b2.id AS id, b2.message AS message, b2.date AS date FROM 
(
    (
        SELECT b.id AS id, b.pid AS pid, b.message AS message, b.date AS date FROM 
        wall_posts AS b 
        JOIN Friends AS f ON f.id = b.pid 
        WHERE f.buddy_id = '1' AND f.status = 'b'
        ORDER BY date DESC
        LIMIT 0, 10
    )
    UNION
    (
        SELECT * FROM
        wall_posts
        WHERE pid = '1'
        ORDER BY date DESC
        LIMIT 0, 10
    )
    ORDER BY date DESC
    LIMIT 0, 10
) AS b2 
JOIN Users AS u
ON b2.pid = u.id
WHERE u.banned='0' AND u.email_activated='1'
ORDER BY date DESC
LIMIT 0, 10

wall_posts表格结构如id date privacy pid uid message

好友表格结构如Fid id buddy_id invite_up_date status

pid代表个人资料ID。我不确定最新情况。

5 个答案:

答案 0 :(得分:18)

UNION中的第一个语句返回四列:

SELECT b.id AS id, 
       b.pid AS pid, 
       b.message AS message, 
       b.date AS date 
  FROM wall_posts AS b 

第二个返回 ,因为*展开以包含WALL_POSTS中的所有列:

SELECT b.id, 
       b.date, 
       b.privacy,
       b.pid. 
       b.uid message
  FROM wall_posts AS b 

UNIONUNION ALL运营商要求:

  1. 构成UNION'd查询的所有语句中存在相同数量的列
  2. 数据类型必须在每个位置/列匹配
  3. 使用:

    FROM ((SELECT b.id AS id, 
                 b.pid AS pid, 
                 b.message AS message, 
                 b.date AS date 
            FROM wall_posts AS b 
            JOIN Friends AS f ON f.id = b.pid 
           WHERE f.buddy_id = '1' AND f.status = 'b'
        ORDER BY date DESC
           LIMIT 0, 10)
          UNION
          (SELECT id,
                  pid,
                  message,
                  date
             FROM wall_posts
            WHERE pid = '1'
         ORDER BY date DESC
            LIMIT 0, 10))
    

答案 1 :(得分:3)

您正在使用6列关系(UNIONidpidmessage)的date relation(* = wall_posts的6列。 SQL不允许你这样做。

答案 2 :(得分:2)

(
        SELECT b.id AS id, b.pid AS pid, b.message AS message, b.date AS date FROM 
        wall_posts AS b 
        JOIN Friends AS f ON f.id = b.pid 
        WHERE f.buddy_id = '1' AND f.status = 'b'
        ORDER BY date DESC
        LIMIT 0, 10
    )
    UNION
    (
        SELECT id, pid  , message , date  
        FROM
        wall_posts
        WHERE pid = '1'
        ORDER BY date DESC
        LIMIT 0, 10
    )

你在第一个查询中选择4,在第二个查询中选择6,所以匹配它们。

答案 3 :(得分:0)

您正在使用MySQL Union。

UNION is used to combine the result from multiple SELECT statements into a single result set.

The column names from the first SELECT statement are used as the column names for the results returned. Selected columns listed in corresponding positions of each SELECT statement should have the same data type. (For example, the first column selected by the first statement should have the same type as the first column selected by the other statements.)

参考:MySQL Union

您的第一条select语句有4列,第二条语句有6列,正如您所说的wall_post有6列。 在两个语句中,您应具有相同的列数和相同的顺序。 否则会显示错误或错误数据。

答案 4 :(得分:0)

除了@ omg-ponies给出的答案外;我只想补充一下,该错误也会在变量分配中发生。在我的情况下,我使用了插入;与该插入关联的是触发器。我错误地将不同数量的字段分配给不同数量的变量。以下是我的案例详细信息。

INSERT INTO tab1 (event, eventTypeID, fromDate, toDate, remarks)
    -> SELECT event, eventTypeID, 
    -> fromDate, toDate, remarks FROM rrp group by trainingCode;
ERROR 1222 (21000): The used SELECT statements have a different number of columns

所以您看到我通过发出插入语句而不是并集语句而收到此错误。我的情况是

  1. 我发布了一个批量插入sql

    即插入tab1(字段,...)作为选择字段,...从tab2中

  2. tab2具有插入时触发;该触发器基本上会减少重复次数

事实证明我在触发器中出错。我根据新的输入数据获取记录,并为其分配了错误数量的变量。

DELIMITER @@
DROP TRIGGER trgInsertTrigger @@
CREATE TRIGGER trgInsertTrigger
BEFORE INSERT ON training
FOR EACH ROW
BEGIN
SET @recs = 0;
SET @trgID = 0;
SET @trgDescID = 0;
SET @trgDesc = '';
SET @district = '';
SET @msg = '';

SELECT COUNT(*), t.trainingID, td.trgDescID, td.trgDescName, t.trgDistrictID
    INTO @recs, @trgID, @trgDescID, @proj, @trgDesc, @district
    from training as t
    left join trainingDistrict as tdist on t.trainingID = tdist.trainingID
    left join trgDesc as td on t.trgDescID = td.trgDescID
    WHERE
    t.trgDescID = NEW.trgDescID
    AND t.venue = NEW.venue
    AND t.fromDate = NEW.fromDate 
    AND t.toDate = NEW.toDate 
    AND t.gender = NEW.gender
    AND t.totalParticipants = NEW.totalParticipants
    AND t.districtIDs = NEW.districtIDs;

IF @recs > 0 THEN
    SET @msg = CONCAT('Error: Duplicate Training: previous ID ', CAST(@trgID AS CHAR CHARACTER SET utf8) COLLATE utf8_bin);
    SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = @msg;
END IF;
END @@ 

DELIMITER ; 

如您所见,我正在获取5个字段,但将其分配给6个变量。 (完全是我的错,我忘记了编辑后删除变量。