запрос db2 для нескольких случаев - PullRequest
0 голосов
/ 03 октября 2018

У меня есть три запроса ниже (идентичные за исключением первой строки предложений WHERE), которые все отлично работают в моем скрипте.Первый запрашивает заказы для клиента, второй - для всех заказов, назначенных представителю, а третий - для всех периодов заказов по всей компании.

Опять же, все они работают с учетом своих соответствующих переменных (все переменные приходятс той же страницы), но я пытаюсь заполнить столбцы в таблице для всех 3 случаев.

Есть ли способ, которым я могу объединить их и создать один запрос, который дает мне одинаковые значения для каждого соответствующего предложения?

Итак, я ожидаю, что все 6 столбцов будут возвращены для одного запроса.Это работает на db2, поэтому я не знаю лучший способ продолжить, но я мог бы создать больший запрос на основе CASE?

//query on orders for this customer
SELECT
    count(*) as sales_180Cust,
    180/count(*) as velocityCust

FROM orders g
    inner join dates i
    on g.date1 = i.acyyyymmdd
WHERE g.cust = $customer
AND g.frm = $frm
AND g.cvr = $cvr
AND g.clr = $clr
AND i.aciso between current_Date - 180 DAY AND current_Date;

//orders belonging to representative
SELECT
    count(*) as sales_180Rep,
    180/count(*) as velocityRep

FROM orders g
    inner join dates i
    on g.date1 = i.acyyyymmdd
WHERE g.rep = $rep
AND g.frm = $frm
AND g.cvr = $cvr
AND g.clr = $clr
AND i.aciso between current_Date - 180 DAY AND current_Date;

//query across ALL orders
SELECT
    count(*) as sales_180Company,
    180/count(*) as velocityCompany

FROM orders g
    inner join dates i
    on g.date1 = i.acyyyymmdd
WHERE g.frm = $frm
AND g.cvr = $cvr
AND g.clr = $clr
AND i.aciso between current_Date - 180 DAY AND current_Date;

Ответы [ 4 ]

0 голосов
/ 03 октября 2018

Или это ... часто существует множество способов сделать что-то в SQL

WITH CTE AS (
    SELECT  g.cust
    ,       g.rep
    FROM orders g
        inner join dates i
        on g.date1 = i.acyyyymmdd
    WHERE 
        g.frm = $frm
    AND g.cvr = $cvr
    AND g.clr = $clr
) , CUST AS (
SELECT
    count(*)     as sales_180Company
,   180/count(*) as velocityCompany
FROM CTE
WHERE cust = $customer
) , REP AS (
SELECT
    count(*)     as sales_180Company
,   180/count(*) as velocityCompany
FROM CTE
WHERE rep = $rep
) , ALL AS (
SELECT
    count(*)     as sales_180Company
,   180/count(*) as velocityCompany
FROM CTE
)
SELECT * FROM CUST, REP, ALL

перенастройка

 SALES_180COMPANY VELOCITYCOMPANY SALES_180COMPANY VELOCITYCOMPANY SALES_180COMPANY VELOCITYCOMPANY
 ---------------- --------------- ---------------- --------------- ---------------- ---------------
                3              60                2              90                5              36
0 голосов
/ 03 октября 2018

Множество способов сделать это.UNION было бы очевидным способом.GROUPING SET s немного умнее.

create table orders(date1 int, rep int, cust int,frm int, cvr int, clr int, aci int);
create table dates(acyyyymmdd int, aciso date);
create variable $frm int default 1;
create variable $cvr int default 1;
create variable $clr int default 1;
create variable $customer int default 1;
create variable $rep int default 1;
insert into orders values (1,0,0,1,1,1,1), (1,1,1,1,1,1,1), (1,2,1,1,1,1,1), (1,3,1,1,1,1,1), (1,1,2,1,1,1,1);
insert into dates values (1, current date); 

тогда это

SELECT
    count(*)     as sales_180Company
,   180/count(*) as velocityCompany
,   g.cust
,   g.rep 
FROM orders g
    inner join dates i
    on g.date1 = i.acyyyymmdd
WHERE 
    g.frm = $frm
AND g.cvr = $cvr
AND g.clr = $clr
AND i.aciso between current_Date - 180 DAY AND current_Date
GROUP BY GROUPING SETS ( (), (cust), (rep) )
HAVING (cust = $customer AND rep is null) 
OR     (cust is null AND rep = $rep)
OR     (cust is null AND rep is null)

дает это

 SALES_180COMPANY VELOCITYCOMPANY CUST REP
 ---------------- --------------- ---- ----
                5              36 NULL NULL
                3              60    1 NULL
                2              90 NULL    1
0 голосов
/ 03 октября 2018

Это был бы другой способ сделать это

WITH CTE AS (
    SELECT  g.cust
    ,       g.rep
    FROM orders g
        inner join dates i
        on g.date1 = i.acyyyymmdd
    WHERE 
        g.frm = $frm
    AND g.cvr = $cvr
    AND g.clr = $clr
)
SELECT
    count(*)     as sales_180Company
,   180/count(*) as velocityCompany
,   'cust' as query
FROM CTE
WHERE cust = $customer
UNION ALL
SELECT
    count(*)     as sales_180Company
,   180/count(*) as velocityCompany
,   'rep' as query
FROM CTE
WHERE rep = $rep
UNION ALL
SELECT
    count(*)     as sales_180Company
,   180/count(*) as velocityCompany
,   'all' as query
FROM CTE

, который возвращает, например,

 SALES_180COMPANY VELOCITYCOMPANY QUERY
 ---------------- --------------- -----
                3              60 cust
                2              90 rep
                5              36 all
0 голосов
/ 03 октября 2018
select q1.*, q2.*, q3.*
from 
  (select count(*) as sales_180Cust,    180/count(*) as velocityCust    from table(values 1) t(i)) q1
, (select count(*) as sales_180Rep,     180/count(*) as velocityRep     from table(values 1, 2) t(i)) q2
, (select count(*) as sales_180Company, 180/count(*) as velocityCompany from table(values 1, 2, 3) t(i)) q3

Я изменил ваши предложения FROM и WERE, чтобы показать идею.

...