ORACLE SQL QUERY union - sql

I have the following table:
site||kw||date
M ||50||1-1-2013
A ||60||1-1-2013
...
I need to show, filtering between two dates
Site||avg(kw)||MAX_KW_PERIOD||MAX_KW_TOTAL
being MAX_KW_PERIOD the maximum value of kw between the two dates and MAX_KW_TOTAL the maximum historical value of kw.
I try with a union query:
SELECT Site,
avg(TM.kw) "AVG_KW",
MAX(TM.kwGen) "MAX KW PERIOD",
TO_NUMBER(NULL) "MAX_TOTAL"
FROM TABLE
WHERE DATE BETWEEN DATE1
AND DATE2
GROUP BY
Site
UNION
SELECT Site,
TO_NUMBER(NULL)"AVG_kW",
TO_NUMBER(NULL)"MAX KW PERIOD",
MAX(TM.kwGEN) "MAX TOTAL"
FROM TABLE
GROUP BY
Site
but i obtain:
SITE||AVG_KW||MAX_KW PERIOD||MAX TOTAL
A||100 ||110 ||(null)
A||(null)||(null) ||160
How can i do to obtain only one row for site like
SITE||AVG_KW||MAX_KW PERIOD||MAX TOTAL
A||100 ||110 ||160
thanks a lot.

Try this:
with maxkw as
((SELECT site, MAX(kw) maxtotal FROM tbl t GROUP BY SITE)),
avgkw as
(SELECT t.Site,
avg(kw) "AVG_KW",
MAX(kw) "MAX_KW_PERIOD"--,
FROM tbl t
WHERE DATE BETWEEN '20130101' AND '20130104'
GROUP BY t.Site)
select t.site, t.avg_kw, t.max_kw_period, c.maxtotal
from avgkw t
inner join maxkw c on t.site = c.site

Related

I want to fetch this data year wise

Select
CIDetail.Itemname,
sum(CIDetail.TaxAmount+ CIDetail.LineAmount) As [TotalAmount]
From
CIDetail (Nolock)
INNER JOIN CIHeader On CIDetail.InvoiceNo= CIHeader.InvoiceNo
Where
CIHeader.InvoiceDate Between '2010-04-01' AND '2014-04-01'
Group By
CIDetail.Itemname
Have a derived table where you use ANSI SQL's EXTRACT to get the year part out of the date, and also add the amounts together. At main level you do GROUP BY both Itemname and year:
Select Itemname, "year", SUM(Amount) as TotalAmount
from
(
CIDetail.Itemname,
extract(year from CIHeader.InvoiceDate) as "year",
CIDetail.TaxAmount + CIDetail.LineAmount As Amount
From
CIDetail (Nolock)
INNER JOIN CIHeader On CIDetail.InvoiceNo= CIHeader.InvoiceNo
) dt
Group By
Itemname, "year"
No dbms tagged in question, but if your dbms doesn't support EXTRACT, try YEAR(CIHeader.InvoiceDate) for example, or something else.
Add to the query a order by clause. Here as you are saying that you want it by date, I will assume that one itemname has only one InvoiceDate. And thus its max will have the same value. You will have to do it as follows
Select CIDetail.Itemname,
sum(CIDetail.TaxAmount+ CIDetail.LineAmount) As [TotalAmount],
From CIDetail (Nolock) INNER JOIN CIHeader
On CIDetail.InvoiceNo= CIHeader.InvoiceNo
Where CIHeader.InvoiceDate Between '2010-04-01' AND '2014-04-01' Group By
CIDetail.Itemname
Order By max(CIHeader.InvoiceDate) ASC

SQL / sum on different date ranges with other conditions

I have the following code:
SELECT
day
,product_id
,product_name
,quantity_on_hand
,inventory_condition
FROM
(
SELECT
table1.product_id as product_id
,table1.product_name as product_name
FROM table1
WHERE
product_id = XXXX
)product_table
,
(
SELECT
table2.day as day
,table2.product_id as inv_product_id
,inventory_condition
,sum( table2.quantity) AS quantity_on_hand
FROM table2
WHERE
table2.day = TO_DATE('{RUN_DATE_YYYY/MM/DD}', 'YYYY/MM/DD')
AND table2.inventory_condition = XXX
GROUP BY
table2.day
,table2.product_id
,inventory_conditio
) inv
WHERE
product_id = inv.product_id
this code works great if I want to extract the data for a single day. But I want to extract the data for 3 different days in the same query. I've tried to use a OR() on my condition on table2.day but it will give me the sum of the data for the 3 days all together. I've also tried to do
Sum() over (Partition by table2.day)
But i'm not sure how to use the syntax.
tahks a lot for your help

How to Sum and Group Union of Two Tables with Different Column Names in SQL Server

The query below successfully returns credit card and check payments for a date range by vendor. I have been unable to write an outer select statement using the aliases to sum the Amount and group by Vendor. How can I do this query?
SELECT
BillPaymentCreditCard.PayeeEntityRefFullName as Vendor, BillPaymentCreditCard.Amount as Amount
FROM
BillPaymentCreditCard NOSYNC
WHERE
BillPaymentCreditCard.TxnDate >= {d'2014-01-01'} and BillPaymentCreditCard.TxnDate <= {d'2014-02-01'}
UNION ALL
SELECT
BillPaymentCheck.PayeeEntityRefFullName as Vendor, BillPaymentCheck.Amount as Amount
FROM
BillPaymentCheck NOSYNC
WHERE
BillPaymentCheck.TxnDate >= {d'2014-01-01'} and BillPaymentCheck.TxnDate <= {d'2014-02-01'}
This should do it. - Per comment - remove the nosync table hints.
SELECT Vendor, SUM(Amount) AS TotalAmount
FROM (
SELECT BillPaymentCreditCard.PayeeEntityRefFullName as Vendor, BillPaymentCreditCard.Amount as Amount
FROM BillPaymentCreditCard
WHERE BillPaymentCreditCard.TxnDate >= {d'2014-01-01'}
and BillPaymentCreditCard.TxnDate <= {d'2014-02-01'}
UNION ALL
SELECT BillPaymentCheck.PayeeEntityRefFullName as Vendor, BillPaymentCheck.Amount as Amount
FROM BillPaymentCheck
WHERE BillPaymentCheck.TxnDate >= {d'2014-01-01'}
and BillPaymentCheck.TxnDate <= {d'2014-02-01'}
) AS Vendors
GROUP BY Vendor

Grouping multiple selects within a SQL query

I have a table Supplier with two columns, TotalStock and Date. I'm trying to write a single query that will give me stock totals by week / month / year for a list of suppliers.
So results will look like this..
SUPPLIER WEEK MONTH YEAR
SupplierA 50 100 2000
SupplierB 60 150 2500
SupplierC 15 25 200
So far I've been playing around with multiple selects but I can't get any further than this:
SELECT Supplier,
(
SELECT Sum(TotalStock)
FROM StockBreakdown
WHERE Date >= '2014-5-12'
GROUP BY Supplier
) AS StockThisWeek,
(
SELECT Sum(TotalStock)
FROM StockBreakdown
WHERE Date >= '2014-5-1'
GROUP BY Supplier
) AS StockThisMonth,
(
SELECT Sum(TotalStock)
FROM StockBreakdown
WHERE Date >= '2014-1-1'
GROUP BY Supplier
) AS StockThisYear
This query throws an error as each individual grouping returns multiple results. I feel that I'm close to the solution but can't work out where to go
You don't have to use subqueries to achieve what you want :
SELECT Supplier
, SUM(CASE WHEN Date >= CAST('2014-05-12' as DATE) THEN TotalStock END) AS StockThisWeek
, SUM(CASE WHEN Date >= CAST('2014-05-01' as DATE) THEN TotalStock END) AS StockThisMonth
, SUM(CASE WHEN Date >= CAST('2014-01-01' as DATE) THEN TotalStock END) AS StockThisYear
FROM StockBreakdown
GROUP BY Supplier
You may need to make the selects for the columns return only a single result. You could try this (not tested currently):
SELECT Supplier,
(
SELECT TOP 1 StockThisWeek FROM
(
SELECT Supplier, Sum(TotalStock) AS StockThisWeek
FROM StockBreakdown
WHERE Date >= '2014-5-12'
GROUP BY Supplier
) tmp1
WHERE tmp1.Supplier = Supplier
) AS StockThisWeek,
(
SELECT TOP 1 StockThisMonth FROM
(
SELECT Supplier, Sum(TotalStock) AS StockThisMonth
FROM StockBreakdown
WHERE Date >= '2014-5-1'
GROUP BY Supplier
) tmp2
WHERE tmp2.Supplier = Supplier
) AS StockThisMonth,
...
This selects the supplier and then tries to create two columns StockThisWeek and StockThisMonth by selecting the first entry from the select you created before. As through the GROUP BY there should only be one entry per supplier, so you don't lose and data.

TERADATA: Aggregate across multiple tables

Consider the following query where aggregation happens across two tables: Sales and Promo and the aggregate values are again used in a calculation.
SELECT
sales.article_id,
avg((sales.euro_value - ZEROIFNULL(promo.euro_value)) / NULLIFZERO(sales.qty - ZEROIFNULL(promo.qty)))
FROM
( SELECT
sales.article_id,
sum(sales.euro_value),
sum(sales.qty)
from SALES_TABLE sales
where year >= 2011
group by article_id
) sales
LEFT OUTER JOIN
( SELECT
promo.article_id,
sum(promo.euro_value),
sum(promo.qty)
from PROMOTION_TABLE promo
where year >= 2011
group by article_id
) promo
ON sales.article_id = promo.article_id
GROUP BY sales.article_id;
Some notes on the query:
Both the inner queries return huge number of rows due to large number of articles. Running explain on teradata, the inner queries themselves take very less time, but the join takes a long time.
Assume primary key on article_id is present and both the tables are partitioned by year.
Left Outer Join because second table contains optional data.
So, can you suggest a better way of writing this query. Thanks for reading this far :)
Not really sure how the avg function got into the mix, so I'm removing it.
SELECT article_id,
(SUM(sales_value) - SUM(promo_value)) /
(SUM(sales_qty) - SUM(promo_qty))
FROM (
SELECT
article_id,
sum(euro_value) AS sales_value,
sum(qty) AS sales_qty,
0 AS promo_value,
0 AS promo_qty
from SALES_TABLE sales
where year >= 2011
group by article_id
UNION ALL
SELECT
article_id,
0 AS sales_value,
0 AS sales_qty,
sum(euro_value) AS promo_value,
sum(qty) AS promo_qty
from SALES_TABLE sales
where year >= 2011
group by article_id
) AS comb
GROUP BY article_id;