Справка SQL-оператора - Избранный последний Порядок на каждого Клиента

Вы можете использовать reduce и concat для получения плоского единого массива.

const sample = [{"key":"sampleKey","values":
  [{"key":"insidesampleKey","value":2},{"key":"insideofinside","value":2}]},

{"key":"sampleKey2","values":[{"key":"insideSampleKey2","value":1}]},

{"key":"samplkey3","values":[{"key":"insideofsampleKey3","value":1}]}]

var values = sample.reduce((acc, item) => acc.concat(item.values.map(v=> v.value)),[]);
console.log(values);

9
задан alextansc 2 December 2008 в 09:58
поделиться

7 ответов

Я не думаю, что Вы действительно хотите использовать МАКСА (), поскольку Вы не хотите группировать OrderID. То, в чем Вы нуждаетесь, является заказанным запросом sub с ИЗБРАННЫМ TOP 1.

select * 
from Customers 
    inner join Orders 
        on Customers.CustomerID = Orders.CustomerID
        and OrderID = (
            SELECT TOP 1 subOrders.OrderID 
            FROM Orders subOrders 
            WHERE subOrders.CustomerID = Orders.CustomerID 
            ORDER BY subOrders.OrderDate DESC
        )
9
ответ дан 4 December 2019 в 09:39
поделиться

Можно использовать функцию окна.

SELECT *
  FROM (SELECT a.*, b.*,
               ROW_NUMBER () OVER (PARTITION BY a.ID ORDER BY b.orderdate DESC,
                b.ID DESC) rn
          FROM customer a, ORDER b
         WHERE a.ID = b.custid)
 WHERE rn = 1

Для каждого клиента (a.id) это сортирует все заказы и отбрасывает все кроме последнего. Пункт ORDER BY включает и дату порядка и идентификатор записи, в случае, если существует несколько заказов на ту же дату.

Обычно функции окна намного быстрее, чем какие-либо поиски с помощью МАКСА () на большом количестве записей.

2
ответ дан 4 December 2019 в 09:39
поделиться

В то время как я вижу, что Вы уже приняли ответ, я думаю, что этот является немного более обладающим интуицией:

select      a.*
           ,b.Id

from       customer a

inner join Order b
on         b.CustomerID = a.Id

where      b.EntryTime = ( select max(EntryTime)
                           from   Order
                           where  Id = b.Id
                         );

Я должен был бы выполнить что-то вроде этого через план выполнения для наблюдения различия в выполнении, но где функция TOP сделана после совершения и что использование "порядка" может быть дорогим, я полагаю, что использование, макс. (EntryTime), было бы лучшим способом выполнить это.

6
ответ дан 4 December 2019 в 09:39
поделиться

Что-то вроде этого должно сделать это:

SELECT X.*, Y.LatestOrderId
FROM Customer X
LEFT JOIN (
  SELECT A.Customer, MAX(A.OrderID) LatestOrderId
  FROM Order A
  JOIN (
    SELECT Customer, MAX(EntryTime) MaxEntryTime FROM Order GROUP BY Customer
  ) B ON A.Customer = B.Customer AND A.EntryTime = B.MaxEntryTime
  GROUP BY Customer
) Y ON X.Customer = Y.Customer

Это предполагает, что два заказов на того же клиента могут иметь тот же EntryTime, который является почему MAX(OrderID) используется в подзапросе Y гарантировать, что это только происходит однажды на клиента. LEFT JOIN используется, потому что Вы заявили, что хотели показать всем клиентам - если у них не будет заказов, то затем LatestOrderId будет NULL.

Надеюсь, это поможет!

--

ОБНОВЛЕНИЕ :-) Это показывает только клиентам с заказами:

SELECT A.Customer, MAX(A.OrderID) LatestOrderId
FROM Order A
JOIN (
  SELECT Customer, MAX(EntryTime) MaxEntryTime FROM Order GROUP BY Customer
) B ON A.Customer = B.Customer AND A.EntryTime = B.MaxEntryTime
GROUP BY Customer
5
ответ дан 4 December 2019 в 09:39
поделиться
SELECT Cust.*, Ord.*
FROM Customers cust INNER JOIN Orders ord ON cust.ID = ord.CustID
WHERE ord.OrderID = 
    (SELECT MAX(OrderID) FROM Orders WHERE Orders.CustID = cust.ID)
0
ответ дан 4 December 2019 в 09:39
поделиться

Один подход, который я еще не видел выше:

SELECT
     C.*,
     O1.ID
FROM
     dbo.Customers C
INNER JOIN dbo.Orders O1 ON
     O1.CustomerID = C.ID
LEFT OUTER JOIN dbo.Orders O2 ON
     O2.CustomerID = C.ID AND
     O2.EntryTime > O1.EntryTime
WHERE
     O2.ID IS NULL

Это (а также другие решения, которым я верю) предполагает, что никакие два заказов на того же клиента не могут иметь то же самое время записи. Если бы это - беспокойство затем, необходимо было бы сделать выбор относительно того, что определяет, какой является "последним". Если это - беспокойство, добавляют комментарий, и я могу развернуть запрос в случае необходимости для составления этого.

Общий подход запроса должен найти порядок на клиента, где нет другого порядка на того же клиента с более поздней датой. Это - затем последний порядок по определению. Этот подход часто дает лучшей производительности затем использование полученных таблиц или подзапросов.

0
ответ дан 4 December 2019 в 09:39
поделиться

Что-то как:

SELECT
  a.*
FROM
  Customer a
    INNER JOIN Order b
      ON a.OrderID = b.Id
        INNER JOIN (SELECT Id, max(EntryTime) as EntryTime FROM Order b GROUP BY Id) met
          ON
            b.EntryTime = met.EntryTime and b.Id = met.Id
0
ответ дан 4 December 2019 в 09:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: