【问题标题】:What is wrong with this INSERT INTO SELECT statement?这个 INSERT INTO SELECT 语句有什么问题?
【发布时间】:2016-06-27 09:49:12
【问题描述】:

我正在尝试运行此代码

INSERT INTO payroll_ho.tb_quotapos(QPCompany,QPQRndYear,QPQRndMonth,QPLine,QPPart,QPDep,QPBand,QPSubBand,QPPos,QPExist1,QPExist2,QPExist3)
SELECT "G02",2016,6,mp.PerWorkLine,mp.PerPart,mp.PerDep,PerBand,PerSubBand,mp.PerPos,c1,c2,c3 FROM ms_per mp
 LEFT JOIN payroll_ho.tb_subbandpos ON BPBand=mp.PerSubBand
 LEFT JOIN (SELECT PerWorkLine,PerPart,PerDep,PerPos,count(*) c1 FROM ms_per WHERE PerQuota=1 AND PerEmploying="Y" AND PerISO="Y"  AND PerCGroup = "01"  GROUP BY PerWorkLine,PerPart,PerDep,PerPos) mp1 ON mp.PerWorkLine=mp1.PerWorkLine AND mp.PerPart=mp1.PerPart AND mp.perdep=mp1.perdep AND mp.perpos=mp1.perpos
 LEFT JOIN (SELECT PerWorkLine,PerPart,PerDep,PerPos,count(*) c2 FROM ms_per WHERE PerQuota=2 AND PerEmploying="Y" AND PerISO="Y"  AND PerCGroup = "01"  GROUP BY PerWorkLine,PerPart,PerDep,PerPos) mp2 ON mp.PerWorkLine=mp2.PerWorkLine AND mp.PerPart=mp2.PerPart AND mp.perdep=mp2.perdep AND mp.perpos=mp2.perpos
 LEFT JOIN (SELECT PerWorkLine,PerPart,PerDep,PerPos,count(*) c3 FROM ms_per WHERE PerQuota=3 AND PerEmploying="Y" AND PerISO="Y"  AND PerCGroup = "01"  GROUP BY PerWorkLine,PerPart,PerDep,PerPos) mp3 ON mp.PerWorkLine=mp3.PerWorkLine AND mp.PerPart=mp3.PerPart AND mp.perdep=mp3.perdep AND mp.perpos=mp3.perpos
 WHERE mp.PerEmploying="Y"
  AND (c1>0 OR c2>0 OR c3>0)
 GROUP BY mp.PerWorkLine,mp.PerPart,mp.PerDep,PerBand,PerSubBand,mp.PerPos
ON DUPLICATE KEY UPDATE QPExist1=c1, QPExist2=c2, QPExist3=c3

MySQL 返回错误Unknown column 'c1' in 'field list' 为什么 MySQL 在SELECT 子句中看不到c1

编辑:我认为问题出在 ON DUPLICATE 子句中。 SELECT 工作正常。

EDIT2:这是每个表的定义。

CREATE TABLE `tb_quotapos` (
  `QPCompany` varchar(3) NOT NULL,
  `QPQRndYear` int(4) NOT NULL,
  `QPQRndMonth` int(2) NOT NULL,
  `QPLine` varchar(2) NOT NULL,
  `QPPart` varchar(3) NOT NULL,
  `QPDep` varchar(4) NOT NULL,
  `QPBand` varchar(2) NOT NULL,
  `QPSubBand` varchar(3) NOT NULL,
  `QPPos` varchar(4) NOT NULL,
  `QPJobDesc` varchar(15) DEFAULT NULL,
  `QPQ1` int(3) DEFAULT NULL,
  `QPQ2` int(3) DEFAULT NULL,
  `QPQ3` int(3) DEFAULT NULL,
  `QPExist1` int(3) DEFAULT NULL,
  `QPExist2` int(3) DEFAULT NULL,
  `QPExist3` int(3) DEFAULT NULL,
  PRIMARY KEY (`QPCompany`,`QPQRndYear`,`QPQRndMonth`,`QPLine`,`QPPart`,`QPDep`,`QPBand`,`QPSubBand`,`QPPos`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8

CREATE TABLE `ms_per` (
  `PerCompany` varchar(3) NOT NULL COMMENT 'รหัสบริษัท/สาขา',
  `PerCode` varchar(8) NOT NULL COMMENT 'รหัสพนักงาน',
  `PerIdenNo` varchar(13) DEFAULT NULL COMMENT 'เลขประจำตัว',
  `PerTitle` varchar(3) DEFAULT NULL COMMENT 'รหัสคำนำหน้า',
  `PerFName` varchar(30) DEFAULT NULL COMMENT 'ชื่อ',
  `PerLName` varchar(30) DEFAULT NULL COMMENT 'นามสกุล',
  `PerEName` varchar(64) DEFAULT NULL COMMENT 'ชื่อภาษาอังกฤษ',
  `PerCGroup` char(6) DEFAULT NULL COMMENT 'รหัสหน่วยงาน',
  `PerWorkLine` char(2) DEFAULT NULL COMMENT 'รหัสสายงาน',
  `PerPart` varchar(4) DEFAULT NULL COMMENT 'ฝ่าย',
  `PerDep` varchar(4) DEFAULT NULL COMMENT 'รหัสแผนก',
  `PerPos` varchar(4) DEFAULT NULL COMMENT 'รหัสตำแหน่ง',
  `PerGroup` varchar(1) DEFAULT NULL COMMENT 'รหัสกลุ่มพนักงาน',
  `PerEmploying` varchar(1) DEFAULT NULL COMMENT 'Y=อยู่ในบริษัท',
  `PerTravel` char(1) DEFAULT NULL COMMENT 'รหัสการเดินทาง',
  `PerTravCode` char(2) DEFAULT NULL COMMENT 'รหัสสายรถ',
  `PerRoomNo` varchar(3) DEFAULT NULL COMMENT 'เลขห้องพัก',
  `PerBand` char(2) DEFAULT '0' COMMENT 'รหัส Band พนักงาน',
  `PerSubBand` char(3) DEFAULT '0' COMMENT 'รหัส Band พนักงาน',
  `PerType` char(3) DEFAULT NULL COMMENT 'ประเภทพนักงาน',
  `PerShift` char(1) DEFAULT NULL COMMENT 'ช่วงเวลาทำงาน (กะ)',
  `PerShiftTime` char(3) DEFAULT '' COMMENT 'รหัส กะ(เวลา) เข้างาน (tb_workshift)',
  `PerDuty` varchar(4) DEFAULT NULL COMMENT 'รหัสหน้าที่',
  `PerDutyDesc` varchar(25) DEFAULT NULL,
  `PerD_M` char(1) DEFAULT 'D' COMMENT 'D:รายวัน  M:รายเดือน',
  `PerQPay` int(1) DEFAULT '2' COMMENT 'จำนวนงวดจ่าย (ต่อเดือน)',
  `PerTPay` char(1) DEFAULT '1' COMMENT 'จ่ายโดย  1:เข้าบัญชี    2:เงินสด',
  `PerQHrPerDay` float(2,0) DEFAULT '8' COMMENT 'จำนวนชั่วโมงทำงาน/วัน (นำมาคำนวณค่าแรง/ช.ม.)',
  `PerQDPerWeek` float(1,0) DEFAULT '6' COMMENT 'จำนวนวันทำงาน/สัปดาห์',
  `PerSoFlag` char(1) DEFAULT 'Y' COMMENT 'Y=เคยยื่นแบบ สปส',
  `PerSoStatus` char(1) DEFAULT 'Y' COMMENT 'Y:เข้าระบบประกันสังคม',
  `PerForeign` char(1) DEFAULT NULL COMMENT 'Y:ต่างด้าว',
  `BeginDate` varchar(6) DEFAULT NULL,
  `PerBeginDate` date DEFAULT NULL COMMENT 'วันเริ่มงาน',
  `BeginFull` varchar(8) DEFAULT NULL,
  `FillDate` varchar(6) DEFAULT NULL,
  `PerFillDate` date DEFAULT NULL COMMENT 'วันบรรจุงาน',
  `EndDate` varchar(6) DEFAULT NULL,
  `PerEndDate` date DEFAULT NULL COMMENT 'วันพ้นสภาพพนักงาน',
  `PerEndCode` char(2) DEFAULT '-' COMMENT 'รหัสการออก/พ้นสภาพพนักงาน',
  `PerEndLevel` char(2) DEFAULT '' COMMENT 'ระดับการพ้นสภาพ',
  `PerQuota` char(1) DEFAULT NULL COMMENT 'โควต้า(อัตรากำลังคน) 1:ชาย 2:หญิง  3:ชายหรือหญิง',
  `PerQuotaNo` varchar(10) DEFAULT NULL COMMENT 'เลขที่ใบขออัตรากำลัง',
  `PerPictFile` varchar(50) DEFAULT NULL COMMENT 'ชื่อไฟล์รูปภาพ',
  `PerLastComp` varchar(35) DEFAULT NULL COMMENT 'ที่ทำงานก่อนหน้านี้',
  `PerSkill` char(1) DEFAULT NULL COMMENT 'รหัสฝีมือ',
  `PerCutShirt` char(1) DEFAULT NULL COMMENT 'มีประกันเสื้อ',
  `PerISO` char(1) DEFAULT 'Y' COMMENT 'Y=เข้าระบบ ISO   N=ไม่เข้า',
  `PerISOType` char(1) DEFAULT '0' COMMENT 'ประเภท ISO',
  `PerTransfer` char(1) DEFAULT '-' COMMENT '9=โอนแล้ว',
  `sPerIdenEDate` varchar(8) DEFAULT NULL,
  `PerIdenEDate` date DEFAULT NULL COMMENT 'วันบัตรหมดอายุ',
  `per_user` varchar(10) DEFAULT NULL,
  `per_comid` varchar(15) DEFAULT NULL,
  `per_update` datetime DEFAULT NULL,
  PRIMARY KEY (`PerCompany`,`PerCode`),
  KEY `PerIdenNo` (`PerIdenNo`) USING BTREE,
  KEY `PerCode` (`PerCode`),
  KEY `PerEmploying` (`PerEmploying`),
  KEY `PerCGroup` (`PerCGroup`),
  KEY `SrchQuota` (`PerWorkLine`,`PerPart`,`PerDep`,`PerPos`,`PerBand`,`PerSubBand`) USING BTREE
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='แฟ้มข้อมูลพนักงาน'

CREATE TABLE `tb_subbandpos` (
  `BPCompany` varchar(3) NOT NULL COMMENT 'รหัสบริษัท',
  `BPBand` varchar(2) NOT NULL COMMENT 'รหัสแบนด์',
  `BPSubBand` varchar(3) NOT NULL COMMENT 'รหัสซับแบนด์',
  `BPPosCode` varchar(4) NOT NULL COMMENT 'รหัสตำแหน่ง',
  PRIMARY KEY (`BPCompany`,`BPBand`,`BPSubBand`,`BPPosCode`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8

【问题讨论】:

  • 看来需要在group by子句中添加c1、c2和c3
  • 您实际上没有这些列 (c1,c2,c3),而是您在内部查询中创建了此名称的别名,这就是无法识别的原因。
  • 使用mp1.c1, mp2.c2 ....
  • @1000111 它不起作用。 “字段列表”中的未知列“mp1.c1”
  • 它应该可以工作。可能你错过了一些需要使用的地方。

标签: mysql select insert


【解决方案1】:

尝试以下操作(注意,我仍在编辑它以恢复数据库名称,我认为表名前面有 2 个位置)。

但是通过涉及派生表来清理列名已经成功了。派生表具有将值折叠到包装它的查询中的奇妙副作用。在这种情况下,它会从 INSERT ON DUPLICATE UPDATE 中删除 group by 禁止性。

INSERT INTO tb_quotapos(QPCompany,QPQRndYear,QPQRndMonth,QPLine,QPPart,QPDep,QPBand,QPSubBand,QPPos,QPExist1,QPExist2,QPExist3)
select col1,col2,col3,col4,col5,col6,col7,col8,col9,col10,col11,col12
from
(   SELECT "G02" as col1,2016 as col2,6 as col3,
    mp.PerWorkLine as col4,mp.PerPart as col5,mp.PerDep as col6,
    PerBand as col7,PerSubBand as col8,mp.PerPos as col9,
    c1 as col10,c2 as col11,c3 as col12 
    FROM ms_per mp
    LEFT JOIN tb_subbandpos ON BPBand=mp.PerSubBand
    LEFT JOIN (SELECT PerWorkLine,PerPart,PerDep,PerPos,count(*) c1 FROM ms_per WHERE PerQuota=1 AND PerEmploying="Y" AND PerISO="Y"  AND PerCGroup = "01"  GROUP BY PerWorkLine,PerPart,PerDep,PerPos) mp1 ON mp.PerWorkLine=mp1.PerWorkLine AND mp.PerPart=mp1.PerPart AND mp.perdep=mp1.perdep AND mp.perpos=mp1.perpos
    LEFT JOIN (SELECT PerWorkLine,PerPart,PerDep,PerPos,count(*) c2 FROM ms_per WHERE PerQuota=2 AND PerEmploying="Y" AND PerISO="Y"  AND PerCGroup = "01"  GROUP BY PerWorkLine,PerPart,PerDep,PerPos) mp2 ON mp.PerWorkLine=mp2.PerWorkLine AND mp.PerPart=mp2.PerPart AND mp.perdep=mp2.perdep AND mp.perpos=mp2.perpos
    LEFT JOIN (SELECT PerWorkLine,PerPart,PerDep,PerPos,count(*) c3 FROM ms_per WHERE PerQuota=3 AND PerEmploying="Y" AND PerISO="Y"  AND PerCGroup = "01"  GROUP BY PerWorkLine,PerPart,PerDep,PerPos) mp3 ON mp.PerWorkLine=mp3.PerWorkLine AND mp.PerPart=mp3.PerPart AND mp.perdep=mp3.perdep AND mp.perpos=mp3.perpos
    WHERE mp.PerEmploying="Y"
    AND (c1>0 OR c2>0 OR c3>0)
    GROUP BY mp.PerWorkLine,mp.PerPart,mp.PerDep,PerBand,PerSubBand,mp.PerPos
) xDerived
ON DUPLICATE KEY UPDATE QPExist1=col10, QPExist2=col11, QPExist3=col12;

第 2 版(有 2 个地方似乎需要payroll_ho.):

INSERT INTO payroll_ho.tb_quotapos(QPCompany,QPQRndYear,QPQRndMonth,QPLine,QPPart,QPDep,QPBand,QPSubBand,QPPos,QPExist1,QPExist2,QPExist3)
select col1,col2,col3,col4,col5,col6,col7,col8,col9,col10,col11,col12
from
(   SELECT "G02" as col1,2016 as col2,6 as col3,
    mp.PerWorkLine as col4,mp.PerPart as col5,mp.PerDep as col6,
    PerBand as col7,PerSubBand as col8,mp.PerPos as col9,
    c1 as col10,c2 as col11,c3 as col12 
    FROM ms_per mp
    LEFT JOIN payroll_ho.tb_subbandpos ON BPBand=mp.PerSubBand
    LEFT JOIN (SELECT PerWorkLine,PerPart,PerDep,PerPos,count(*) c1 FROM ms_per WHERE PerQuota=1 AND PerEmploying="Y" AND PerISO="Y"  AND PerCGroup = "01"  GROUP BY PerWorkLine,PerPart,PerDep,PerPos) mp1 ON mp.PerWorkLine=mp1.PerWorkLine AND mp.PerPart=mp1.PerPart AND mp.perdep=mp1.perdep AND mp.perpos=mp1.perpos
    LEFT JOIN (SELECT PerWorkLine,PerPart,PerDep,PerPos,count(*) c2 FROM ms_per WHERE PerQuota=2 AND PerEmploying="Y" AND PerISO="Y"  AND PerCGroup = "01"  GROUP BY PerWorkLine,PerPart,PerDep,PerPos) mp2 ON mp.PerWorkLine=mp2.PerWorkLine AND mp.PerPart=mp2.PerPart AND mp.perdep=mp2.perdep AND mp.perpos=mp2.perpos
    LEFT JOIN (SELECT PerWorkLine,PerPart,PerDep,PerPos,count(*) c3 FROM ms_per WHERE PerQuota=3 AND PerEmploying="Y" AND PerISO="Y"  AND PerCGroup = "01"  GROUP BY PerWorkLine,PerPart,PerDep,PerPos) mp3 ON mp.PerWorkLine=mp3.PerWorkLine AND mp.PerPart=mp3.PerPart AND mp.perdep=mp3.perdep AND mp.perpos=mp3.perpos
    WHERE mp.PerEmploying="Y"
    AND (c1>0 OR c2>0 OR c3>0)
    GROUP BY mp.PerWorkLine,mp.PerPart,mp.PerDep,PerBand,PerSubBand,mp.PerPos
) xDerived
ON DUPLICATE KEY UPDATE QPExist1=col10, QPExist2=col11, QPExist3=col12;

由于Group By,派生表是必需的。来自手册页INSERT ... SELECT Syntax

在 ON DUPLICATE KEY UPDATE 的值部分,可以参考 其他表中的列,只要不使用 GROUP BY 选择部分。一个副作用是您必须限定非唯一列 值部分中的名称。

感谢Justin 在他的回答here。不过,我确实提供了上面手册页的更新链接。

【讨论】:

  • 是的,这就是我想要的答案!非常感谢。如果你有时间,也许你可以在这里帮助另一个问题。对你的帮助表示感谢。 stackoverflow.com/questions/38047673/…
  • 吃一点后就可以了。很高兴它奏效了。我正在计划一个派生的包装,但坦率地说,直到我在谷歌之后阅读贾斯汀的评论之前,我认为没有必要。
  • 啊,这个问题。我正在考虑回到那个。之前看过。
猜你喜欢
  • 2011-06-01
  • 1970-01-01
  • 2011-12-04
  • 2010-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多