sql server复杂查询在视图中

时间:2016-08-25 09:42:19

标签: sql-server

我有两张名为' PackageDelivery'和' Delivery'

在表格中Delivery_ID'我有2列Delivery_RankPackageDelivery

在表Package_ID中,我有2列Delivery_ID1457 1589 1457 1590 1457 1591

对于此表中的相同Package_ID,我们可以拥有多个delivery_ID。 因此,表Delivery中的Delivery_Rank可以增加与我们具有相同Package_id的Delivery_id一样多

例如,在PackageDelivery表中,我们有以下记录:

package_id

列分别为delivery_id1589 1 1590 2 1591 3

在表格交付中,我们有以下记录

delivery_id

列分别为delivery_rank 1457 1589 1591

我需要只有一个查询在同一行上检索具有较低Delivery_Rank的package_id和delivery_ID以及具有较高Delivery_Rank的Delivery_id 对于上面的例子,我需要检索:

with cte as(
select package_id,d.delivery_id, delivery_rank from packagedelivery pd inner join delivery d on pd.delivery_id=d.delivery_id where package_id=37453)
,cte2 as (
select top 1 delivery_id as firstdelivery_id ,package_id from cte order by delivery_rank asc)
,cte3 as(
select top 1 delivery_id as lastdelivery_id ,package_id from cte order by delivery_rank desc)

select distinct c1.package_id,c2.firstdelivery_id,c3.lastdelivery_id
from cte c1 inner join cte2 c2 on c1.Package_ID=c2.Package_ID
inner join cte3 c3 on c2.Package_ID=c3.Package_ID

困难在于查询必须在视图中,并且所需的package_id必须位于视图外部的子句中

这就是我的所作所为:

@Entity
public class Books{

@Id(autoincrement = true)
private Long id;
private double LATITUDE;
private double LONGITUDE;
private Date LASTSYNC;

@NotNull
private FeedbackStatus FEEDBACK;
private long TIMESTAMP;
}

但正如我所说,查询必须放在视图中,而package_id必须放在视图之外。

有办法吗?

提前多多感谢

2 个答案:

答案 0 :(得分:0)

尝试这样

编辑第一个答案是错误的......

如果PackageDelivery-Table中有多个package_ids,我的第一次尝试无法正常工作。这应该更好:

DECLARE @Delivery TABLE(delivery_id INT,delivery_rank INT);
DECLARE @PackageDelivery TABLE(package_id INT,delivery_id INT);

INSERT INTO @PackageDelivery VALUES
 (1457,1589)
,(1457,1590)
,(1457,1591)
,(1000,2000);

INSERT INTO @Delivery VALUES
 (1589,1)
,(1590,2)
,(1591,3)
,(2000,2);

- 这是您VIEW

的代码
WITH Numbered AS
(
    SELECT pd.package_id
          ,d.delivery_id
          ,ROW_NUMBER() OVER(PARTITION BY pd.package_id ORDER BY d.delivery_rank ASC ) AS SortUp
          ,ROW_NUMBER() OVER(PARTITION BY pd.package_id ORDER BY d.delivery_rank DESC) AS SortDown
    FROM @PackageDelivery AS pd
    INNER JOIN @Delivery AS d on pd.delivery_id=d.delivery_id
)
SELECT n.package_id
      ,MAX(CASE WHEN SortUp=1 THEN n.delivery_id END) AS MinRank
      ,MAX(CASE WHEN SortDown=1 THEN n.delivery_id END) AS MaxRank
FROM Numbered AS n
GROUP BY n.package_id

在外面,您可以使用package_id

设置WHERE

另一个 - 可能更好 - 方法是使用package_id作为参数的内联TVF ...

答案 1 :(得分:0)

如果您使用的是SQL Server 2012或更高版本,那么我会坚持使用Min和Max窗口函数。以下示例显示了特定问题的视图示例。

CREATE VIEW MyPackageView
AS
SELECT      package_id
            ,MIN(delivery_id) AS min_delivery_id
            ,MAX(delivery_id) AS max_delivery_id
FROM        (
                SELECT      P.package_id
                            ,P.delivery_id
                            ,D.delivery_rank
                            ,MIN(D.delivery_rank) OVER (PARTITION BY P.package_id) AS min_delivery_rank
                            ,MAX(D.delivery_rank) OVER (PARTITION BY P.package_id) AS max_delivery_rank
                FROM        PackageDelivery P
                INNER JOIN  Delivery D ON P.delivery_id = D.delivery_id
            ) RankedPackageDelivery
WHERE       (delivery_rank = min_delivery_rank) OR (delivery_rank = max_delivery_rank)
GROUP BY    package_id