如何将前1个字段正确连接到SQL查询
如何将注释块中的字段正确地连接到SQL查询?我在订单头上有一个计费电话号码,但在订单行上,每行都有一个发货电话号码。账单和运输可以不同 在一个订单的每一个订单行上,99%的发货数量相同,但我想做前1名,而不是分组,以防一些数据弄乱 我认为UNION可能会满足我的需求,但似乎有更好的方法可以在一个查询中获取所有内容,而不是复制和粘贴相同的where子句如何将前1个字段正确连接到SQL查询,sql,sql-server,tsql,sql-server-2012,Sql,Sql Server,Tsql,Sql Server 2012,如何将注释块中的字段正确地连接到SQL查询?我在订单头上有一个计费电话号码,但在订单行上,每行都有一个发货电话号码。账单和运输可以不同 在一个订单的每一个订单行上,99%的发货数量相同,但我想做前1名,而不是分组,以防一些数据弄乱 我认为UNION可能会满足我的需求,但似乎有更好的方法可以在一个查询中获取所有内容,而不是复制和粘贴相同的where子句 SELECT a.Order_no ,a.Customer_no ,a.BILL_LAST_NAME ,
SELECT a.Order_no
,a.Customer_no
,a.BILL_LAST_NAME
,a.BILL_FIRST_NAME
,b.email
,a.BILL_ADDRESS1
,a.BILL_ADDRESS2
,a.BILL_CITY
,a.BILL_STATE
,a.BILL_POSTAL_CODE
,a.BILL_COUNTRY
,b.Address_Type
,a.BILL_PHONE
,a.BILL_PHONE_EXT
,a.Order_Date
,a.billing_status
,a.PO_Number
,a.Customer_comments
,a.ShipMethodShipperDesc
,a.ShipRate
,a.CouponDiscountCode
,a.CouponDiscount
,a.CustomerDiscount
,a.CustomerDiscountPercent
,a.SalesTaxTotal
,a.Payment_Method
,a.Credit_Card_Type
,a.Credit_Card_Number
,a.Order_Date
,a.BILL_TYPE
,a.Order_Net
/* I added these lines but would like them joined properly */
/*-------->*/
, (select top 1 SHIP_ADDRESS1 from LineItems C where c.ORDER_NO = a.ORDER_NO)
, (select top 1 SHIP_ADDRESS2 from LineItems C where c.ORDER_NO = a.ORDER_NO)
, (select top 1 SHIP_CITY from LineItems C where c.ORDER_NO = a.ORDER_NO)
, (select top 1 SHIP_STATE from LineItems C where c.ORDER_NO = a.ORDER_NO)
, (select top 1 SHIP_POSTAL_CODE from LineItems C where c.ORDER_NO = a.ORDER_NO)
, (select top 1 SHIP_COUNTRY from LineItems C where c.ORDER_NO = a.ORDER_NO)
/*<-----------*/
FROM Orders AS a
,Customers AS b
WHERE a.customer_no = b.customer_no
AND a.AccountName = 'mywebaccount'
AND a.billing_status <> 'Canceled'
AND a.transferred = 0
AND a.order_status <> 'Canceled'
AND EXISTS (
SELECT *
FROM LineItems c
WHERE c.order_no = a.order_no
)
ORDER BY a.order_date
,a.order_no
首先,不要从一些表1做t1,一些表2做t2。始终显式联接。其次,从您的案例外观来看,APPLY的一些变体非常适合
以下是我的版本:
SELECT a.Order_no
,a.Customer_no
,a.BILL_LAST_NAME
,a.BILL_FIRST_NAME
,b.email
,a.BILL_ADDRESS1
,a.BILL_ADDRESS2
,a.BILL_CITY
,a.BILL_STATE
,a.BILL_POSTAL_CODE
,a.BILL_COUNTRY
,b.Address_Type
,a.BILL_PHONE
,a.BILL_PHONE_EXT
,a.Order_Date
,a.billing_status
,a.PO_Number
,a.Customer_comments
,a.ShipMethodShipperDesc
,a.ShipRate
,a.CouponDiscountCode
,a.CouponDiscount
,a.CustomerDiscount
,a.CustomerDiscountPercent
,a.SalesTaxTotal
,a.Payment_Method
,a.Credit_Card_Type
,a.Credit_Card_Number
,a.Order_Date
,a.BILL_TYPE
,a.Order_Net
,li.SHIP_ADDRESS1
,li.SHIP_ADDRESS2
,li.SHIP_CITY
,li.SHIP_STATE
,li.SHIP_POSTAL_CODE
,li.SHIP_COUNTRY
FROM Orders AS a
INNER JOIN Customers AS b
ON a.customer_no = b.customer_no
CROSS APPLY
(
SELECT TOP 1 c.SHIP_ADDRESS1
,c.SHIP_ADDRESS2
,c.SHIP_CITY
,c.SHIP_STATE
,c.SHIP_POSTAL_CODE
,c.SHIP_COUNTRY
FROM LineItems c
WHERE c.ORDER_NO = a.ORDER_NO
ORDER BY c.Id -- or whatever
) AS li
WHERE a.AccountName = 'mywebaccount'
AND a.billing_status <> 'Canceled'
AND a.transferred = 0
AND a.order_status <> 'Canceled'
-- no need for that exists since CROSS APPLY works like INNER JOIN
ORDER BY a.order_date,a.order_no
我建议如下:
SELECT Order_no
,Customer_no
,BILL_LAST_NAME
,BILL_FIRST_NAME
...
,SHIP_ADDRESS1
,SHIP_ADDRESS2
,SHIP_CITY
,SHIP_STATE
,SHIP_POSTAL_CODE
,SHIP_COUNTRY
FROM (
SELECT a.Order_no
,a.Customer_no
,a.BILL_LAST_NAME
,a.BILL_FIRST_NAME
,b.email
,a.BILL_ADDRESS1
,a.BILL_ADDRESS2
,a.BILL_CITY
,a.BILL_STATE
,a.BILL_POSTAL_CODE
,a.BILL_COUNTRY
,b.Address_Type
,a.BILL_PHONE
,a.BILL_PHONE_EXT
,a.Order_Date
,a.billing_status
,a.PO_Number
,a.Customer_comments
,a.ShipMethodShipperDesc
,a.ShipRate
,a.CouponDiscountCode
,a.CouponDiscount
,a.CustomerDiscount
,a.CustomerDiscountPercent
,a.SalesTaxTotal
,a.Payment_Method
,a.Credit_Card_Type
,a.Credit_Card_Number
,a.Order_Date
,a.BILL_TYPE
,a.Order_Net
,c.SHIP_ADDRESS1
,c.SHIP_ADDRESS2
,c.SHIP_CITY
,c.SHIP_STATE
,c.SHIP_POSTAL_CODE
,c.SHIP_COUNTRY
, row_number() over (partition by a.order_no
order by SHIP_ADDRESS1, SHIP_ADDRESS2, SHIP_CITY, SHIP_STATE
, SHIP_POSTAL_CODE, SHIP_COUNTRY) as rn
FROM Orders AS a
JOIN Customers AS b
ON a.customer_no = b.customer_no
JOIN numberLineItems c
ON c.order_no = a.order_no
WHERE a.AccountName = 'mywebaccount'
AND a.billing_status <> 'Canceled'
AND a.transferred = 0
AND a.order_status <> 'Canceled'
) as x
WHERE rn = 1
ORDER BY order_date
, order_no;
我创建了一个简单的示例并发布了 最简单的方法就是从子查询中与前1联接
select cus.*, ord.*, sub.*
from Customer cus
join [Order] ord on ord.CustomerId = cus.Id
join (
select it.OrderId, it.ItemName, it.ItemAddress
from Items it
where it.Id in (select MAX(id) from Items group by OrderId)
) as sub on sub.OrderId = ord.Id
如果要查看第一项而不是最后一项,可以将MAXid替换为MINid
请注意,唯一的问题是,如果订单中没有项目,它将不会显示。
但是,如果您收到的订单中没有项目,但仍然希望显示该项目,则可以使用左连接
用小提琴演奏一个跑步的例子
我希望您不介意我使用显式连接=您可以使用子查询进行连接,在子查询中可以将其放在顶部。顺便说一句,很长一段时间我没有看到隐式连接我如何用子查询连接多个字段?您只连接订单号并检索多个列。但是,是的,您可以在join中使用任何布尔谓词。我将查询的最后一部分更改为此,但它不起作用。但是我觉得我很接近:从订单a内部连接客户b在b上。客户号=a。客户号无内部连接从c上的行项目c中选择前1个订单号,发货地址1,发货地址2,发货城市,发货州,发货邮政编码,发货国家。订单号=a。订单号看起来比原来的好多了。当然,当使用TOP时,我们还需要有一个order by。@SeanLange是的,当我更担心得到不可靠的缩进而不是完成查询时,就会发生这种情况。已编辑。交叉应用是否比使用分区更好?我最终使用了分区method@user1387756我认为在速度方面也差不多。就风格而言,我更喜欢我的方法,因为我发现它更具可读性,应用是做你需要的事情的正确方法。不幸的是,我没有可靠的Id。你真的不需要Id,你可以得到任意项,在子查询中有很多方法可以得到它:交叉应用、分区、哈希、行数等等