SQL возвращает максимальное значение от дочернего для каждой родительской строки - PullRequest
3 голосов
/ 29 сентября 2011

У меня есть 2 таблицы - 1 с родительскими записями, 1 с дочерними записями. Для каждой родительской записи я пытаюсь вернуть одну дочернюю запись с MAX (SalesPriceEach).

Кроме того, я хотел бы возвращать значение только при наличии более 1 дочерней записи.

parent - SalesTransactions table:
+-------------------+---------+
|SalesTransaction_ID|   text  |
+-------------------+---------+
| 1                 |  Blah   |
| 2                 |  Blah2  |
| 3                 |  Blah3  |
+-------------------+---------+

child - SalesTransactionLines table 
+--+-------------------+---------+--------------+
|id|SalesTransaction_ID|StockCode|SalesPriceEach|
+--+-------------------+---------+--------------+
| 1|   1               |  123    | 99           |
| 2|   1               |   35    | 50           |
| 3|   2               |   15    | 75           |
+--+-------------------+---------+--------------+


 desired results
+-------------------+---------+--------------+
|SalesTransaction_ID|StockCode|SalesPriceEach|
+-------------------+---------+--------------+
|   1               |  123    | 99           |
|   2               |   15    | 75           |
+-------------------+---------+--------------+

Я нашел очень похожий вопрос здесь и основал свой запрос на ответе, но не вижу ожидаемых результатов.

WITH max_feature AS (
   SELECT c.StockCode,
          c.SalesTransaction_ID,
          MAX(c.SalesPriceEach)  as feature
     FROM SalesTransactionLines c
 GROUP BY c.StockCode, c.SalesTransaction_ID)
   SELECT p.SalesTransaction_ID,
          mf.StockCode,
          mf.feature
     FROM SalesTransactions p
LEFT JOIN max_feature mf ON mf.SalesTransaction_ID = p.SalesTransaction_ID

Результаты этого запроса возвращают несколько строк для каждого родителя, и даже не самое высокое значение сначала!

Ответы [ 4 ]

3 голосов
/ 12 сентября 2012

Я знаю, что я опоздал на эту вечеринку на год, но я всегда предпочитаю использовать Row_Number в таких ситуациях. Он решает проблему, когда есть две строки, которые соответствуют критериям Max, и гарантирует, что возвращается только одна строка:

with z as (
select 
    st.SalesTransaction_ID
    ,row=ROW_NUMBER() OVER(PARTITION BY st.SalesTransaction_ID ORDER BY stl.SalesPriceEach DESC)
    ,stl.StockCode
    ,stl.SalesPriceEach
from 
    SalesTransactions st
    inner join SalesTransactionLines stl on stl.SalesTransaction_ID = st.SalesTransaction_ID
)
select * from z where row = 1   
2 голосов
/ 29 сентября 2011
select stl.SalesTransaction_ID, stl.StockCode, ss.MaxSalesPriceEach
from SalesTransactionLines stl
inner join 
(
    select stl2.SalesTransaction_ID, max(stl2.SalesPriceEach) MaxSalesPriceEach
    from SalesTransactionLines stl2 
    group by stl2.SalesTransaction_ID
    having count(*) > 1
) ss on (ss.SalesTransaction_ID = stl.SalesTransaction_ID and 
         ss.MaxSalesPriceEach = stl.SalesPriceEach)

ИЛИ, альтернативно:

SELECT stl1.*
FROM SalesTransactionLines AS stl1
LEFT OUTER JOIN SalesTransactionLines AS stl2
ON (stl1.SalesTransaction_ID = stl2.SalesTransaction_ID 
    AND stl1.SalesPriceEach < stl2.SalesPriceEach)
WHERE stl2.SalesPriceEach IS NULL;
0 голосов
/ 29 сентября 2011
select a.SalesTransaction_ID, a.StockCode, a.SalesPriceEach
from SalesTransacions as a 
  inner join (select SalesTransaction_ID, MAX(SalesPriceEach) as SalesPriceEach  
              from SalesTransactionLines group by SalesTransaction_ID) as b
    on a.SalesTransaction_ID = b.SalesTransaction_ID 
       and a.SalesPriceEach = b.SalesPriceEach

подзапрос возвращает таблицу с идентификаторами транзакций и их максимумами, поэтому просто объедините их с самой таблицей транзакций этими двумя значениями

0 голосов
/ 29 сентября 2011
SELECT SalesTransactions.SalesTransaction_ID, 
       SalesTransactionLines.StockCode, 
       MAX(SalesTransactionLines.SalesPriceEach) 
FROM  SalesTransactions RIGHT JOIN SalesTransactionLines 
      ON SalesTransactions.SalesTransaction_ID = SalesTransactionLines.SalesTransaction_ID 
GROUP BY SalesTransactions.SalesTransaction_ID, alesTransactionLines.StockCode;
...