我试图找出哪些顾客在一家餐厅连续2次下订单。我正在使用两个表Orders和Order_rank。
Order_rank包含客户成功订单的计数-例如如果订单编号的订单等级为2,则该订单是该客户自注册以来的第二次连续订单。
订单:
DataTable dt = new DataTable();
string Secteur, Reference, Title, DateLimite, DatePublication, Lieux;
dt.Columns.Add("Secteur", typeof(string));
dt.Columns.Add("Reference", typeof(string));
dt.Columns.Add("Title", typeof(string));
dt.Columns.Add("DateLimite", typeof(string));
dt.Columns.Add("DatePublication", typeof(string));
dt.Columns.Add("Lieux", typeof(string));
try
{
using (SPSite site = new SPSite(SPContext.Current.Site.Url))
{
using (SPWeb web = site.OpenWeb())
{
SPList list = web.Lists["Offres"];
SPListItemCollection coll = list.Items;
foreach (SPListItem item in coll)
{
if (item["Secteur"] != null)
{
Secteur = item["Secteur"].ToString();
}
else
{
Secteur = "";
}
if (item["Reference"] != null)
Reference = item["Reference"].ToString();
else
Reference = " ";
if (item["Title"] != null)
Title = item["Title"].ToString();
else
Title = " ";
if (item["DateLimite"] != null)
DateLimite = item["DateLimite"].ToString();
else
DateLimite = " ";
if (item["DatePublication"] != null)
DatePublication = item["DatePublication"].ToString();
else
DatePublication = " ";
if (item["Lieux"] != null)
Lieux = item["Lieux"].ToString();
else
Lieux = " ";
dt.Rows.Add(Secteur, Reference, Title, DateLimite,
DatePublication, Lieux);
}
OffresGrid.DataSource = dt;
OffresGrid.DataBind();
}
}
}
catch (Exception )
{
}
Order_rank:
Createdate | Orderid | OrderStatus | Customerid | Restaurantname
---------- | ------- | ----------- | ---------- | --------------
2019-08-03 | 1338 | Accepted | 45 | KFC
2019-08-04 | 3266 | Accepted | 45 | KFC
2019-08-06 | 1595 | Null | 37 | Burger King
2019-08-07 | 9258 | Null | 89 | KFC
2019-08-12 | 4853 | Accepted | 22 | Burger King
2019-08-13 | 5682 | Null | 22 | Burger King
2019-08-14 | 3515 | Accepted | 16 | Burger King
2019-08-16 | 2495 | Accepted | 16 | KFC
2019-08-22 | 2359 | Accepted | 35 | KFC
2019-08-25 | 2456 | Null | 47 | Burger King
我要显示的输出是这样的:
Customerid | Orderid | Rank
---------- | ------- | ----
16 | 2495 | 2
16 | 3515 | 2
22 | 4853 | 3
22 | 5682 | 1
35 | 2359 | 1
37 | 1595 | 1
45 | 1338 | 2
45 | 3266 | 2
47 | 2456 | 3
我需要显示两个连续订单的订单日期。
我该如何实现?
这是我尝试过的方法,但是并没有达到我想要的效果:
Customerid | Createdate | Orderid | RestaurantName
---------- | ---------- | ------- | --------------
45 | 2019-08-03 | 1338 | KFC
45 | 2019-08-04 | 3266 | KFC
答案 0 :(得分:0)
如果您只想在order_rank表中显示排名为2的订单,我想,您需要做的就是将Order表通过Orderid连接到Order_rank并为Rank = 2放置WHERE语句,如果您也想考虑等级为3或更高的等级,只需更改为Rank> = 2。
SELECT Orders.Customerid,
Orders.Createdate,
Orders.Orderid,
Orders.Restaurantname
FROM Orders LEFT OUTER JOIN Order_rank ON (Orders.Orderid=Order_rank.Orderid)
WHERE Order_rank.Rank=2;
答案 1 :(得分:0)
如果我理解正确,那么我会将其视为“缺口和岛屿问题”,并执行以下操作:
USE Sandbox;
GO
/*
Createdate | Orderid | OrderStatus | Customerid | Restaurantname
---------- | ------- | ----------- | ---------- | --------------
2019-08-03 | 1338 | Accepted | 45 | KFC
2019-08-04 | 3266 | Accepted | 45 | KFC
2019-08-06 | 1595 | Null | 37 | Burger King
2019-08-07 | 9258 | Null | 89 | KFC
2019-08-12 | 4853 | Accepted | 22 | Burger King
2019-08-13 | 5682 | Null | 22 | Burger King
2019-08-14 | 3515 | Accepted | 16 | Burger King
2019-08-16 | 2495 | Accepted | 16 | KFC
2019-08-22 | 2359 | Accepted | 35 | KFC
2019-08-25 | 2456 | Null | 47 | Burger King
*/
--Sample Data
WITH VTE AS(
SELECT CONVERT(date,V.Createdate) AS Createdate,
V.Orderid,
NULLIF(RTRIM(V.OrderStatus),'null') AS OrderStatus,
V.Customerid,
RTRIM(V.Restaurantname) AS Restaurantname
FROM (VALUES('2019-08-03',1338,'Accepted',45,'KFC '),
('2019-08-04',3266,'Accepted',45,'KFC '),
('2019-08-06',1595,'Null ',37,'Burger King'),
('2019-08-07',9258,'Null ',89,'KFC '),
('2019-08-12',4853,'Accepted',22,'Burger King'),
('2019-08-13',5682,'Null ',22,'Burger King'),
('2019-08-14',3515,'Accepted',16,'Burger King'),
('2019-08-16',2495,'Accepted',16,'KFC '),
('2019-08-22',2359,'Accepted',35,'KFC '),
('2019-08-25',2456,'Null ',47,'Burger King'))V(Createdate,Orderid,OrderStatus,Customerid,Restaurantname)),
--Solution
Grps AS(
SELECT V.Createdate,
V.Orderid,
V.OrderStatus,
V.Customerid,
V.Restaurantname,
ROW_NUMBER() OVER (PARTITION BY V.Customerid ORDER BY V.Orderid) -
ROW_NUMBER() OVER (PARTITION BY V.Customerid,V.Restaurantname ORDER BY V.Orderid) AS Grp
FROM VTE V),
Counts AS(
SELECT G.Createdate,
G.Orderid,
G.OrderStatus,
G.Customerid,
G.Restaurantname,
G.Grp,
COUNT(*) OVER (PARTITION BY G.Customerid,G.Grp) AS ConsecOrders
FROM Grps G)
SELECT C.Createdate,
C.Orderid,
C.OrderStatus,
C.Customerid,
C.Restaurantname
FROM Counts C
WHERE C.ConsecOrders > 1;
请注意,我在上面的结果集中得到了4行:
Createdate Orderid OrderStatus Customerid Restaurantname
---------- ----------- ----------- ----------- --------------
2019-08-12 4853 Accepted 22 Burger King
2019-08-13 5682 NULL 22 Burger King
2019-08-03 1338 Accepted 45 KFC
2019-08-04 3266 Accepted 45 KFC
我认为这是预料之中的,因为客户22连续从汉堡王那里定购了订单(只是其中的一项不被接受)。如果您只想接受已接受的订单,则应该很容易就能算出在何处添加适当的WHERE
。
答案 2 :(得分:0)
我认为您可能想在Orders_rank上尝试DENSE_RANK()
,因为与RANK()
不同,DENSE_RANK()
返回连续的排名值。
SELECT
o.*
FROM dbo.Orders AS o
INNER JOIN (SELECT
Customerid
, Orderid
, DENSE_RANK() OVER (PARTITION BY Rank ORDER BY Customerid) AS Consec
FROM dbo.Orders_Rank
WHERE Rank = 2) AS r ON o.Customerid = r.Customerid
AND o.Orderid = r.Orderid
AND r.Consec = 2
WHERE o.OrderStatus = 'Accepted'
AND o.Restaurantname = 'KFC';
一如既往,可能会有更优雅的方法来解决此问题,但类似的事情应该可以解决。
答案 3 :(得分:0)
使用可以使用lag()
和lead()
:
select o.* -- whatever columns you want
from (select o.*, orr.customerid,
lag(o.restaurant) over (partition by o.customerid order by createddate) as prev_restaurant,
lead(o.restaurant) over (partition by o.customerid order by createddate) as next_restaurant
from orders o
) o
where restaurant = 'KFC' and
restaurant in (prev_restaurant, next_restaurant);
除非您出于过滤目的需要使用order_rank
,否则我在查询中看不到任何用处。