【发布时间】:2019-02-28 16:21:44
【问题描述】:
使用 MSSQL:只是为了澄清
客户表
CustomerNumber Name
===================
1 David
2 Thomas
3 Mangold
4 Issac
------------------------------------------------------------
客户地址表
CustomerNumber State EffectiveDate
==================================
1 AL 01/01/2017
1 VA 06/01/2017
1 GA 02/01/2018
1 FL 10/01/2018
2 TX 01/01/2017
3 MA
4 IL 04/01/2015
SalesOrder 表
CUSTOMER ORDERNo OrderDate
========================
1 1000 03/01/2017
2 1001 10/10/2017
1 1002 11/01/2017
3 1003 12/01/2017
4 1004 01/01/2018
1 1005 02/01/2018
1 1006 01/01/2019
我需要在订单日期获取所有带有客户详细信息和客户地址的订单。
SELECT T1.ORDERNo, T1.ORDERDATE, T1.CUSTOMER, T2.NAME, T3.STATE
FROM SALESORDER T1, CUSTOMER T2, CUSTOMERADDRESS T3
RIGHT JOIN(
SELECT CUSTOMER, MAX(EFFECTIVEDATE) FROM CUSTOMERADDRESS
--WHERE EFFECTIVEDATE <= T1.ORDERDATE
GROUP BY CUSTOMER)T4
ON T3.CUSTOMER = T4.CUSTOMER AND T3.EFFECTIVEDATE=T4.EFFECTIVEDATE
WHERE T1.CUSTOMER = T2.CUSTOMERNUMBER
AND T1.CUSTOMER = T3.CUSTOMERNUMBER
想看看如何在连接中进行比较,我将第一个表与连接中的第三个表进行比较。见注释代码--WHERE EFFECTIVEDATE <= T1.ORDERDATE
如果我删除注释代码,则连接中的表无法引用外部表。
预期的输出是:
CUSTOMER ORDERNo OrderDate CustomerName State
=============================================
1 1000 03/01/2017 David AL
2 1001 10/10/2017 Thomas TX
1 1002 11/01/2017 David VA
3 1003 12/01/2017 Mangold MA
4 1004 01/01/2018 Issac IL
1 1005 02/01/2018 David GA
1 1006 01/01/2019 David FL
sql fiddlehttp://sqlfiddle.com/#!18/9eecb中的表:
CREATE TABLE Customer
('CustomerNumber' int, 'CustomerName' varchar(30))
;
INSERT INTO Customer
('CustomerNumber', 'CustomerName')
VALUES
(1, 'David'),
(2, 'Thomas'),
(3, 'Mangold'),
(4, 'Issac')
;
CREATE TABLE CustomerAddress
('CustomerNumber' int, 'State' varchar(2), 'EffectiveDate' date)
;
INSERT INTO CustomerAddress
('CustomerNumber', 'State', 'EffectiveDate')
VALUES
(1, 'AL', 01/01/2017),
(1, 'VA', 06/01/2017),
(1, 'GA', 02/01/2018),
(1, 'FL', 10/01/2018),
(2, 'TX', 01/01/2017),
(3, 'MA',),
(4, 'IL', 04/01/2015)
;
CREATE TABLE SalesOrder
('CUSTOMER' int, 'ORDERNO' int, 'OrderDate' Date)
;
INSERT INTO SalesOrder
('CUSTOMER', 'ORDERNO', 'OrderDate')
VALUES
(1, 1000, 03/01/2017),
(2, 1001, 10/10/2017),
(1, 1002, 11/01/2017),
(3, 1003, 12/01/2017),
(4, 1004, 01/01/2018),
(1, 1005, 02/01/2018),
(1, 1006, 01/01/2019)
;
CREATE TABLE CustomerAddress
(`CustomerNumber` int, 'State' varchar(2), `EffectiveDate` date)
;
INSERT INTO CustomerAddress
(`CustomerNumber`, `State`, 'EffectiveDate')
VALUES
(1, 'AL', 01/01/2017),
(1, 'VA', 06/01/2017),
(1, 'GA', 02/01/2018),
(1, 'FL', 10/01/2018),
(2, 'TX', 01/01/2017),
(3, 'MA',),
(4, 'IL', 04/01/2015)
;
CREATE TABLE SalesOrder
(`CUSTOMER` int, 'ORDERNO' int, `OrderDate` Date)
;
INSERT INTO SalesOrder
(`CUSTOMER `, `ORDERNO`, 'OrderDate')
VALUES
(1, 1000, 03/01/2017),
(2, 1001, 10/10/2017),
(1, 1002, 11/01/2017),
(3, 1003, 12/01/2017),
(4, 1004, 01/01/2018),
(1, 1005, 02/01/2018),
(1, 1006, 01/01/2019)
;
'sql 服务器版本'
CREATE TABLE Customer
(CustomerNumber int, CustomerName varchar(30))
;
INSERT INTO Customer
(CustomerNumber, CustomerName)
VALUES
(1, 'David'),
(2, 'Thomas'),
(3, 'Mangold'),
(4, 'Issac');
;
CREATE TABLE CustomerAddress
(CustomerNumber int, State varchar(2), EffectiveDate date)
;
INSERT INTO CustomerAddress
(CustomerNumber, State, EffectiveDate)
VALUES
(1, 'AL', '01/01/2017'),
(1, 'VA', '06/01/2017'),
(1, 'GA', '02/01/2018'),
(1, 'FL', '10/01/2018'),
(2, 'TX', '01/01/2017'),
(4, 'IL', '04/01/2015')
;
INSERT INTO CustomerAddress
(CustomerNumber, State)
VALUES
(3, 'MA' )
;
CREATE TABLE SalesOrder
(CUSTOMER int, ORDERNO int, OrderDate Date)
;
INSERT INTO SalesOrder
(CUSTOMER, ORDERNO, OrderDate)
VALUES
(1, 1000, '03/01/2017'),
(2, 1001, '10/10/2017'),
(1, 1002, '11/01/2017'),
(3, 1003, '12/01/2017'),
(4, 1004, '01/01/2018'),
(1, 1005, '02/01/2018'),
(1, 1006, '01/01/2019')
;
问题:需要选择所有销售订单及其客户名称和客户地址。重要且棘手的部分是客户地址更改基于销售订单的日期。
--不完整查询的修改版本
SELECT T1.ORDERNo, T1.ORDERDATE, T1.CUSTOMER, T2.CustomerName, T3.STATE
FROM CUSTOMER T2, SALESORDER T1 INNER JOIN CUSTOMERADDRESS T3 ON T1.CUSTOMER = T3.CUSTOMERNUMBER
RIGHT JOIN(
SELECT CustomerNumber, MAX(EFFECTIVEDATE) as EffectiveDate4 FROM CUSTOMERADDRESS
--WHERE EFFECTIVEDATE < T1.ORDERDATE
GROUP BY CustomerNumber
--HAVING EFFECTIVEDATE < T1.ORDERDATE
) T4
ON T3.CustomerNumber = T4.CustomerNumber AND T3.EFFECTIVEDATE=T4.EffectiveDate4
WHERE T1.CUSTOMER = T2.CUSTOMERNUMBER
【问题讨论】:
-
首先,是时候开始使用 ANSI-92 样式连接了。它们已经上市超过 25 年了。 sqlblog.org/2009/10/08/bad-habits-to-kick-using-old-style-joins 另外,使用具有某种含义的别名,T1、T2 不是一个好主意。 sqlblog.org/2009/10/08/… 此外,您应该避免为对象使用保留名称。 “订单”是一个糟糕的表格名称。
-
我怀疑这可以大大简化,但不确定您在这里要做什么。你期望输出什么?
-
别名很方便,但通用别名不方便。它们使事情变得更加困难,因为您必须不断地参考别名来弄清楚别名的含义。在您的查询而不是 T1、T2、T3 中,我会使用类似 c 和 ca 的东西
-
正如当前发布的那样,customeraddress 无关紧要,因为您不包含该表中的任何列。所以重新开始。您的查询和您声明的目标根本不匹配。在开始编写查询之前了解您的目标。分步编写查询。正确加入地址不是您的解决方案的一部分 - 这是一种保证。
-
这里给出的示例数据,不包含任何地址信息。你想通过正确的加入来完成什么?
标签: sql-server right-join