跨具有不同列名的表的SQL子查询

时间:2012-07-08 22:50:03

标签: mysql sql subquery

假设我有两个表:orderinfocustomerinfo

他们看起来像这样:

订单信息:

OrderID
CustomerID
OrderCustomerName
OrderCustomerAddress

customerinfo:

CustomerID
CustomerName
CustomerAddress

OrderIDCustomerID都是唯一的。当要创建订单时,我需要将客户信息从customerinfo复制到orderinfo,因为客户可能会在以后更改其信息。

我希望我可以使用CustomerID来实现这一目标。我该如何编写子查询?感谢。

3 个答案:

答案 0 :(得分:2)

当您插入新订单时,您可以使用以下简单的INSERT... SELECT查询语法获取客户数据的“快照”

INSERT INTO orderinfo (CustomerID, OrderCustomerName, OrderCustomerAddress, status) 
SELECT CustomerID, CustomerName, CustomerAddress, 'P'
FROM customerinfo
WHERE CustomerID = <customerid here>

这会在订单下达的确切时间插入包含客户信息的新订单。

即使客户在customerinfo表中更新了他或她的信息,此信息仍将保留,因为除了CustomerID更改之外没有任何级联效应(它不应该,即使它确实改变了,它也不会改变“快照”数据。)

答案 1 :(得分:1)

要根据orderinfo使用客户名称和地址的当前值更新CustomerID,请使用UPDATE JOIN

UPDATE
  orderinfo
  JOIN customerinfo ON orderinfo.CustomerID = customerinfo.CustomerID
SET 
  OrderCustomerName = CustomerName,
  OrderCustomerAddress = CustomerAddress
WHERE OrderID = <some_order_id>

如果您希望“冻结”与特定订单相关联的客户信息,即使客户稍后在全球范围内更改了该信息,这也非常有用。如果我理解正确,那就是你的意图。

您也可以使用AFTER INSERT表格上的orderinfo触发器执行此操作。然后,您无需执行单独的查询:

CREATE TRIGGER update_order_cust_info AFTER INSERT ON orderinfo
FOR EACH ROW 
BEGIN
    UPDATE
      orderinfo
      JOIN customerinfo ON orderinfo.CustomerID = customerinfo.CustomerID
    SET 
      NEW.OrderCustomerName = CustomerName,
      NEW.OrderCustomerAddress = CustomerAddress
    WHERE OrderID = NEW.OrderID
END

答案 2 :(得分:1)

您正在寻找的是

INSERT INTO orderinfo 
    (OrderID, CustomerID, OrderCustomerName, OrderCustomerAddress)
VALUES (
    '12345', 
    '789',
    (SELECT CustomerName FROM customerinfo WHERE CustomerID = '789'),
    (SELECT CustomerAddress FROM customerinfo WHERE CustomerID = '789')
)

但我强烈建议您更改数据库结构。您尝试执行的操作违反了Database Normalisation rules。相反,请在Slowly Changing Dimensions上阅读维基百科上的这篇文章并实现它。