428

私は単純なmysqlテーブルを持っています:

CREATE TABLE IF NOT EXISTS `pers` (
  `persID` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(35) NOT NULL,
  `gehalt` int(11) NOT NULL,
  `chefID` int(11) DEFAULT NULL,
  PRIMARY KEY (`persID`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;

INSERT INTO `pers` (`persID`, `name`, `gehalt`, `chefID`) VALUES
(1, 'blb', 1000, 3),
(2, 'as', 1000, 3),
(3, 'chef', 1040, NULL);

次の更新を実行しようとしましたが、エラー 1093 しか表示されません。

UPDATE pers P 
SET P.gehalt = P.gehalt * 1.05 
WHERE (P.chefID IS NOT NULL 
OR gehalt < 
(SELECT (
    SELECT MAX(gehalt * 1.05) 
    FROM pers MA 
    WHERE MA.chefID = MA.chefID) 
    AS _pers
))

エラーを検索し、mysql の次のページhttp://dev.mysql.com/doc/refman/5.1/en/subquery-restrictions.htmlから見つけましたが、役に立ちません。

SQLクエリを修正するにはどうすればよいですか?

4

11 に答える 11

857

問題は、MySQLが、なんらかの理由で、次のようなクエリを記述できないことです。

UPDATE myTable
SET myTable.A =
(
    SELECT B
    FROM myTable
    INNER JOIN ...
)

つまり、テーブルでUPDATE//を実行している場合、内部クエリでそのテーブルを参照することはできませんただし、その外部テーブルからフィールドを参照することはできます... INSERTDELETE


myTable解決策は、サブクエリ内ののインスタンスを次の(SELECT * FROM myTable)ように置き換えることです。

UPDATE myTable
SET myTable.A =
(
    SELECT B
    FROM (SELECT * FROM myTable) AS something
    INNER JOIN ...
)

これにより、必要なフィールドが暗黙的に一時テーブルにコピーされるようになるため、許可されます。

私はここでこの解決策を見つけました。その記事からのメモ:

SELECT * FROM table実生活では、サブクエリだけにしたくはありません。例を単純にしておきたかっただけです。実際には、その最も内側のクエリで必要な列のみを選択しWHERE、結果を制限するための適切な句を追加する必要があります。

于 2013-01-13T10:45:06.070 に答える
53

これは、次の 3 つの手順で作成できます。

CREATE TABLE test2 AS
SELECT PersId 
FROM pers p
WHERE (
  chefID IS NOT NULL 
  OR gehalt < (
    SELECT MAX (
      gehalt * 1.05
    )
    FROM pers MA
    WHERE MA.chefID = p.chefID
  )
)

...

UPDATE pers P
SET P.gehalt = P.gehalt * 1.05
WHERE PersId
IN (
  SELECT PersId
  FROM test2
)
DROP TABLE test2;

また

UPDATE Pers P, (
  SELECT PersId
  FROM pers p
  WHERE (
   chefID IS NOT NULL 
   OR gehalt < (
     SELECT MAX (
       gehalt * 1.05
     )
     FROM pers MA
     WHERE MA.chefID = p.chefID
   )
 )
) t
SET P.gehalt = P.gehalt * 1.05
WHERE p.PersId = t.PersId
于 2010-12-13T13:47:21.777 に答える
27

Mysql では、同じテーブルをサブクエリして 1 つのテーブルを更新することはできません。

クエリを 2 つの部分に分けることができます。

UPDATE TABLE_A AS A
 INNER JOIN TABLE_A AS B ON A.field1 = B.field1
 SET field2 = ?
于 2012-03-09T21:40:12.520 に答える
25

サブクエリから一時テーブル (tempP) を作成する

UPDATE pers P 
SET P.gehalt = P.gehalt * 1.05 
WHERE P.persID IN (
    SELECT tempP.tempId
    FROM (
        SELECT persID as tempId
        FROM pers P
        WHERE
            P.chefID IS NOT NULL OR gehalt < 
                (SELECT (
                    SELECT MAX(gehalt * 1.05) 
                    FROM pers MA 
                    WHERE MA.chefID = MA.chefID) 
                    AS _pers
                )
    ) AS tempP
)

別の名前 (エイリアス) を導入し、一時テーブルの「persID」列に新しい名前を付けました

于 2012-07-18T01:43:52.753 に答える
18

とても簡単です。たとえば、次のように書く代わりに:

INSERT INTO x (id, parent_id, code) VALUES (
    NULL,
    (SELECT id FROM x WHERE code='AAA'),
    'BBB'
);

あなたは書くべきです

INSERT INTO x (id, parent_id, code)
VALUES (
    NULL,
    (SELECT t.id FROM (SELECT id, code FROM x) t WHERE t.code='AAA'),
    'BBB'
);

または類似。

于 2012-09-19T14:58:18.663 に答える
3

tableA から fieldA を読み取り、同じテーブルの fieldB に保存しようとしている場合、fieldc = fieldd の場合、これを考慮する必要があります。

UPDATE tableA,
    tableA AS tableA_1 
SET 
    tableA.fieldB= tableA_1.filedA
WHERE
    (((tableA.conditionFild) = 'condition')
        AND ((tableA.fieldc) = tableA_1.fieldd));

上記のコードは、条件フィールドが条件を満たしたときにフィールド A からフィールド B に値をコピーします。これは ADO でも機能します (例: access )

出典:自分でやってみた

于 2013-05-08T09:37:44.560 に答える