ORACLE Select list inconsistant with group by - oracle

I can't create my view and I don't know how to fix it.
when trying to create the view it tries to add all the columns from select to the group by, which isn't what I want. and doesn't work anyways
CREATE OR REPLACE FORCE VIEW CustomerSaleHistoryView AS
Select SALE.SaleID,
SALE.SaleDate,
CUSTOMER.LastName,
CUSTOMER.FirstName,
SALE_ITEM.SaleItemID,
SALE_ITEM.ItemID,
ITEM.ItemPrice,
SUM(SALE_ITEM.ITEMPRICE),
AVG(SALE_ITEM.ITEMPRICE)
from customer
join sale on customer.CUSTOMERID = Sale.CUSTOMERID
join sale_item on sale_item.saleid = sale.saleID
join item on sale_item.itemID = item.itemID
group by CUSTOMER.LastName, CUSTOMER.FirstName, SALE.SaleID;

In order for you query to work you MUST group by any columns that are not being aggregated with a formula like SUM() or AVG(). In your case GROUP BY SALE.SaleID, SALE.SaleDate, CUSTOMER.LastName, CUSTOMER.FirstName, SALE_ITEM.SaleItemID, SALE_ITEM.ItemID, ITEM.ItemPrice
What are you trying to accomplish that you don't believe this GROUP BY is appropriate?

When using group by clause the list of columns that you are selecting should be either part of the group by clause or they should be part of an aggregate function. In your case SALE.SaleDate, SALE_ITEM.SaleItemID, SALE_ITEM.ItemID and ITEM.ItemPrice doesn't satisfy that rule. You need to include these to your group by clause. Once you fix the select statement and when it returns the desired output convert that into a view.

Related

Oracle: remove duplicates from select results in specific columns

I need to create a view contains BSB#, customer#, name from customer, and account#, type, balance from account.
I tried this select statement:
select customer.bsb#, customer.customer#, customer.name, account.account#, account.type, account.balance
from customer
left outer join account on customer.bsb# = account.bsb#
and customer.customer# = account.customer#;
And the output is like this:
output
However, I need to make the out like:
display
So, how could I remove the duplicate results from certain columns?

HIve join without common filed

I have the following tables:
Table1:
user_name Url
Rahul www.cric.info.com
ranbir www.rogby.com
sahil www.google.com
banit www.yahoo.com
Table2:
Keyword category
cric sports
footbal sports
google search
I want to search Table1 by matching the keyword in Table2. I can perform the same using case statement and the query works but it is not the right approach because each time I have to add the case statement when I will add new search keyword.
select user_name from table1
case when url like '%cric%' then sports
else 'undefined'
end as category
from table1;
Thanks find the soluntions for this approach. FIrst we need to do the Join and after that we need to filter the record.
select user_name,url,Keyword,catagory from(select table1.user_name,table1.url ,table2.keyword,table2.catagory from table1 left outer join table2)a where a.url like (concat('%',a.phrase,'%')
Not sure about more current versions, but I've run into a similar problem... the primary issue is that Hive only supports equi-join statements... when you apply logic to either side of the join, it has difficulty translating into a Map Reduce function.
The alternative method, if you have a reliably structured field, is that you can create a matching key from the larger field. For example, if you know that you're looking for your keyword to exist in the second position of a dot-delimited URI, you could do something like:
select
Uri
, split(Uri, "\\.")[1] as matchKey
from
Table1
join Table2 on Table2.keyword = Table1.matchKey
;

Need to select column from subquery into main query

I have a query like below - table names etc. changed for keeping the actual data private
SELECT inv.*,TRUNC(sysdate)
FROM Invoice inv
WHERE (inv.carrier,inv.pro,inv.ndate) IN
(
SELECT carrier,pro,n_dt FROM Order where TRUNC(Order.cr_dt) = TRUNC(sysdate)
)
I am selecting records from Invoice based on Order. i.e. all records from Invoice which are common with order records for today, based on those 3 columns...
Now I want to select Order_Num from Order in my select query as well.. so that I can use the whole thing to insert it into totally seperate table, let's say orderedInvoices.
insert into orderedInvoices(seq_no,..same columns as Inv...,Cr_dt)
(
SELECT **Order.Order_Num**, inv.*,TRUNC(sysdate)
FROM Invoice inv
WHERE (inv.carrier,inv.pro,inv.ndate) IN
(
SELECT carrier,pro,n_dt FROM Order where TRUNC(Order.cr_dt) = TRUNC(sysdate)
)
)
?? - how to do I select that Order_Num in main query for each records of that sub query?
p.s. I understand that trunc(cr_dt) will not use index on cr_dt (if a index is there..) but I couldn't select records unless I omit the time part of it..:(
If the table ORDER1 is unique on CARRIER, PRO and N_DT you can use a JOIN instead of IN to restrict your records, it'll also enable you to select whatever data you want from either table:
select order.order_num, inv.*, trunc(sysdate)
from Invoice inv
join order ord
on inv.carrier = ord.carrier
and inv.pro = ord.pro
and inv.ndate = ord.n_dt
where trunc(order.cr_dt) = trunc(sysdate)
If it's not unique then you have to use DISTINCT to deduplicate your record set.
Though using TRUNC() on CR_DT will not use an index on that column you can use a functional index on this if you do need an index.
create index i_order_trunc_cr_dt on order (trunc(cr_dt));
1. This is a really bad name for a table as it's a keyword, consider using ORDERS instead.

Linq Sum for Multiple Joins

Can someone help me out with the following Linq statement? I'm trying to get join 4 tables through Linq, group by the last table and sum a property of the first.
var payments = (
from payment in db.Payments
join payees in db.cmsMembers on payment.PayeeID equals payees.nodeId
join payeeGroups in db.cmsMember2MemberGroups on payees.nodeId equals payeeGroups.Member
join groups in db.umbracoNodes on payeeGroups.MemberGroup equals groups.id
group groups by new {groups.text, payment} into groupedPayments
select new
{
Group = groupedPayments.Key.text,
Count = groupedPayments.Count(),
Amount = groupedPayments.Sum(?)
}
).ToList();
The issue I'm having is that the in the groupedPayments.Sum(..) call I'm only getting access to the "groups" object. This is fine for the Group name and count aspect but the SUM has to be performed on the payment.Amount property.
I've managed to resolve my issue. I hadn't realised that the object in the group declaration would become the actual object witin the resulting group item. By altering the original statement to the following:
group payment by groups into groupedPayments
it seems that each instance of groupedPayments.Key in the select statement now corresponds to the payment row which is what I required.

Linq to SQL: order by value in related table

I have 2 tables which in simplified form look like this:
Products(
id: int,
name: varchar
);
ProductSpecs(
product_id: int,
spec_name: varchar,
spec_value: int
);
Now I need to sort products (in linq to sql) by value of some specification item (eg. "price"). So I do something like this
var products = from p in db.Products
from ps in p.ProductsSpecs
where ps.spec_name == "price"
orderby ps.spec_value
select p;
The problem is that if there's no such ProductSpec with spec_name "price" the product is not included at all. I can add these products with Union or Concat but this way the sorting of the first part is not preserved.
What is the best way to deal with this?
Thanks.
First, I would recommend that you either do this in pure SQL as a function or Stored Procedure and then access this through linq, or add a price column to your product table. It seems like price would be a normal attribute to add to all of your products even if that price is NULL.
SQL:
select p.*
from products p
left outer join productspecs ps on
p.id = ps.product_id
and ps.spec_name = 'Price'
order by ps.spec_value
With that said, here's the weird bit of LINQ that should work on your table (I might have some of the column names spelled incorrectly):
var products = from p in db.Products
join ps in (from pss in db.ProductSpecs
where pss.spec_name== "Price"
select pss
) on p.id equals ps.product_id into temp
from t in temp.DefaultIfEmpty()
orderby t.spec_value
select p;
I tested this on some tables setup like above and created 5 products, three with prices in different value orders and this LINQ ordered them just like the SQL above and returned the null result rows as well.
Hope this works!
In ordinary SQL, you'd use an LEFT OUTER JOIN. This preserves rows that appear in the left-hand table (the one listed first), even when there's no matching row in the right-hand table (the second one listed, and the one that is outer joined). You end up with nulls for the values that should be, but weren't, present in the right-hand table. So, the price for those items missing a price would appear as NULL.
What that translates to in LINQ to SQL is another matter.
You might care to think about whether it is reasonable to have products that do not have a price. You're emulating something called EAV - Entity, Attribute, Value - tables, and they are generally regarded as 'not a good thing'.
Can you not just do a simple join?
var products =
from p in db.Products
join ps in db.ProductSpecs on p.id equals ps.product_id
where ps.spec_name == "price"
orderby ps.spec_value
select p;

Resources