У меня есть два таких вопроса:

Первый:

select p.prodid, p.name, max(b.ldate) as lastsale 
from prod p, buy b 
where p.id = b.idprod and b.id<>0  and b.wskus=0 and b.bufor=0
group by p.prodid, p.name
HAVING sum(b.curNo)=0
order by p.name asc

Второй

select p.prodid, p.name, min(b.buydate) as oldest_buy 
from prod p, buy b         
where p.id = b.idprod and b.id<>0  and b.wskus=0 and b.bufor=0 and b.curNo>0
group by p.prodid, p.name
order by p.name asc

Как я могу сделать JOIN, чтобы в результате были столбцы:

| p.prodid | p.name | lastsale | oldest_buy |
| 1        | ex1    | 1.1.18   | NULL       |
| 2        | ex2    | NULL     | 1.1.18     |

Поскольку HAVING sum(b.curNo)=0 из первого запроса является эксклюзивным для параметра WHERE из второго запроса b.curNo>0, у меня проблема, как заставить это работать.

0
Paweł Madej 3 Янв 2018 в 02:36

2 ответа

Лучший ответ

Без ваших входных данных сложно сказать, но возможно, это сработает для вас ...

SELECT
  p.prodid,
  p.name,
  MIN(CASE WHEN b.curNo > 0 THEN b.buydate END)     AS oldest_buy,   -- MIN(buydate) WHERE curno>0
  CASE WHEN SUM(b.curNo) = 0 THEN MAX(b.ldate) END  AS lastsale      -- MAX(ldate) HAVING SUM(curNo) = 0
FROM
  prod p
INNER JOIN   -- Don't use "," use "JOIN"s, the standard for about 25 years...
  buy b
    ON p.id = b.idprod
WHERE
      b.id    <> 0
  AND b.wskus  = 0
  AND b.bufor  = 0
GROUP BY
  p.prodid,
  p.name
ORDER BY
  p.name  ASC


Возможно, что перемещение b.curNo > 0 или SUM(b.curNo) = 0 в операторы CASE приведет к появлению дополнительных строк в зависимости от поведения ваших данных. Невозможно сказать без более подробной информации или данных примеров.

Значения в двух вычислениях будут в порядке, но я не могу говорить о количестве строк.

Чтобы быть более точным, вы могли бы сделать ...

SELECT
  p.prodid,
  p.name,
  CASE WHEN MAX(b.curNo) > 0 THEN MIN(CASE WHEN b.curNo > 0 THEN b.buydate END) END    AS oldest_buy,
  CASE WHEN SUM(b.curNo) = 0 THEN MAX(b.ldate)                                  END   AS lastsale
FROM
  prod p
INNER JOIN   -- Don't use "," use "JOIN"s, the standard for about 25 years...
  buy b
    ON p.id = b.idprod
WHERE
      b.id    <> 0
  AND b.wskus  = 0
  AND b.bufor  = 0
GROUP BY
  p.prodid,
  p.name
HAVING
     SUM(b.curNo) = 0
  OR MAX(b.curNo) > 0
ORDER BY
  p.name  ASC


Другая возможность (опять же, потому что вы не указали данные примера) - это агрегирование, а затем присоединение.

Это основано на том, что вы имеете в виду p.curNo, а не b.curNo ...

SELECT
  p.prodid,
  p.name,
  CASE p.curNo > 0 THEN b.oldest_buy END   AS oldest_buy,
  CASE p.curNo = 0 THEN b.last_sale  END   AS lastsale
FROM
  prod p
INNER JOIN   -- Don't use "," use "JOIN"s, the standard for about 25 years...
(
  SELECT
     idprod,
     MIN(buydate)    AS oldest_buy,
     MAX(ldate)      AS last_sale
  FROM
     buy
  WHERE
        b.id    <> 0
    AND b.wskus  = 0
    AND b.bufor  = 0
)
  b
    ON p.id = b.idprod
ORDER BY
  p.name  ASC
1
MatBailie 3 Янв 2018 в 10:43

Поместите первый запрос в подзапрос перед объединением всех. Попробуй это:

select 
t.prodid, t.name, t.lastsale, null as oldest_buy
from (select p.prodid, p.name, 
             max(b.ldate) as lastsale 
      from   prod p, buy b 
      where  p.id = b.idprod and b.id<>0  and 
             b.wskus=0 and b.bufor=0
      group by p.prodid, p.name
      HAVING sum(b.curNo)=0 ) t
union all
( select p.prodid, p.name, 
  null as lastsale, min(b.buydate) as oldest_buy 
  from prod p, buy b        
  where p.id = b.idprod and b.id<>0  and b.wskus=0 
  and b.bufor=0 and b.curNo>0
  group by p.prodid, p.name )
order by 2 asc
0
kc2018 3 Янв 2018 в 00:32