Informix: Query merge - sql

i have 2 queries:
select COUNT(o.id_offer) from offers o, product p where
p.id_product = "+ productID +" and o.id_offer = "+ offerID +" and (b.type = 0 or o.type = "A")
this query returns the count of some product
select p.id_product, p.name, s.id_supplier, s.name from product p, suppliers s where p.id_supplier = s.id_supplier
this query returns all products data
i want to combine the two queries in one, something like this:
select (select COUNT(o.id_offer) from offers o, product p where
p.id_product = p.id_product and o.id_offer = 13345 and (b.type = 0 or o.type = "A")) count,p.id_product, p.name, s.id_supplier, s.name from product p, suppliers s where p.id_supplier = s.id_supplier
Anyone knows how to do this in informix?

Please use the explicit join notation, not the comma-list of table names in the FROM clause notation.
The first query needs generalizing to generate a product ID and the matching count.
SELECT p.id_product, COUNT(o.id_offer) AS offer_count
FROM offers o
JOIN product p ON p.id_product = o.id_product -- Guessed column
WHERE (p.type = 0 OR o.type = 'A')
GROUP BY p.id_product
The second query can be converted to:
SELECT p.id_product, p.name, s.id_supplier, s.name
FROM product p
JOIN suppliers s ON p.id_supplier = s.id_supplier
These two queries can be combined with a join, too:
SELECT x.id_product, x.product_name, x.id_supplier, x.supplier_name, y.offer_count
FROM (SELECT p.id_product, p.name, s.id_supplier, s.name
FROM product p
JOIN suppliers s ON p.id_supplier = s.id_supplier
) AS x
JOIN (SELECT p.id_product, COUNT(o.id_offer) AS offer_count
FROM offers o
JOIN product p ON p.id_product = o.id_product -- Guessed column
WHERE (p.type = 0 OR o.type = 'A')
GROUP BY p.id_product
) AS y
ON x.id_product = y.id_product

Related

SQL Two result from one column in 2 columns

i have checked some similar issues in the forum but i can't seems to get it to work properly.
i'm on phpmyadmin
i need to get a result like that :
Reference | ProductNameEnglish | ProductNameFrench
What's blocking me is to do 2 requests on the same column (pl.name) :/
Here is my query for now :
SELECT
p.reference AS Reference,
(SELECT pl.name
FROM ps_product p
LEFT JOIN ps_product_lang pl ON (p.id_product = pl.id_product)
WHERE p.active = 1
AND pl.id_lang = 2) AS ENname,
(SELECT pl.name
FROM ps_product p
LEFT JOIN ps_product_lang pl ON (p.id_product = pl.id_product)
WHERE p.active = 1
AND pl.id_lang = 1) AS FRname
FROM ps_product p
You don't need the join in the subqueries:
SELECT p.reference AS Reference,
(SELECT pl.name
FROM ps_product_lang pl
WHERE p.id_product = pl.id_product AND
p.active = 1 AND
pl.id_lang = 2
) AS ENname,
(SELECT pl.name
FROM ps_product_lang pl
WHERE p.id_product = pl.id_product AND
p.active = 1 AND
pl.id_lang = 1
) AS FRname
FROM ps_product p;
This assumes that only one row matches the subqueries. You may need to limit the results to a single row if that is not the case.
SELECT
p.reference AS Reference,
pl.name as ENname,
pf.name as FRname
FROM ps_product p
LEFT JOIN ps_product_lang pl ON (p.id_product = pl.id_product and pl.id_lang = 1)
LEFT JOIN ps_product_lang pf ON (p.id_product = pf.id_product and pf.id_lang = 2)
WHERE p.active = 1
I might have switched English and French, but that should be easy to fix....

Oracle SQL How to Count Column Value Occurences and Group BY during joins

I'm working on another SQL query, trying to group a collection of records while doing a count and joining tables. See below for goal, current query, and attached scripts for building and populating tables.
Show all customers who have checked more books than DVDs. Display
customer name, total book checkouts and total DVD checkouts. Sort
results by customer first name and last name.
SELECT C.CUSTOMER_FIRSTNAME, C.CUSTOMER_LASTNAME, COUNT(T.TRANSACTION_ID)
FROM customer C
INNER JOIN library_card LC ON C.CUSTOMER_ID = LC.CUSTOMER_ID
INNER JOIN transaction T ON LC.LIBRARY_CARD_ID = T.LIBRARY_CARD_ID
INNER JOIN physical_item P ON T.PHYSICAL_ITEM_ID = P.PHYSICAL_ITEM_ID
INNER JOIN catalog_item CT ON P.CATALOG_ITEM_ID = CT.CATALOG_ITEM_ID
GROUP BY C.CUSTOMER_FIRSTNAME, C.CUSTOMER_LASTNAME
ORDER BY C.CUSTOMER_FIRSTNAME, C.CUSTOMER_LASTNAME;
Run first: https://drive.google.com/open?id=1PYAZV4KIfZtxP4eQn35zsczySsxDM7ls
Run second: https://drive.google.com/open?id=1pAzWmJqvD3o3n6YJqVUM6TtxDafKGd3f
EDIT
With some help from Mr. Barbaros I've come up with the below query, which is closer. However, this query isn't returning any results for DVDs, which leads me to believe it's a join issue.
SELECT C.CUSTOMER_FIRSTNAME, C.CUSTOMER_LASTNAME, COUNT(CT1.TYPE) AS BOOK_COUNT, COUNT(CT2.TYPE) AS DVD_COUNT
FROM customer C
INNER JOIN library_card LC ON C.CUSTOMER_ID = LC.CUSTOMER_ID
INNER JOIN transaction T ON LC.LIBRARY_CARD_ID = T.LIBRARY_CARD_ID
INNER JOIN physical_item P ON T.PHYSICAL_ITEM_ID = P.PHYSICAL_ITEM_ID
INNER JOIN catalog_item CT1 ON P.CATALOG_ITEM_ID = CT1.CATALOG_ITEM_ID AND CT1.TYPE = 'BOOK'
LEFT OUTER JOIN catalog_item CT2 ON P.CATALOG_ITEM_ID = CT2.CATALOG_ITEM_ID AND CT2.TYPE = 'DVD'
GROUP BY C.CUSTOMER_FIRSTNAME, C.CUSTOMER_LASTNAME, CT1.TYPE, CT2.TYPE
ORDER BY C.CUSTOMER_FIRSTNAME, C.CUSTOMER_LASTNAME;
Use "conditional aggregates" (use a case expression inside the aggregate function)
SELECT
C.CUSTOMER_FIRSTNAME
, C.CUSTOMER_LASTNAME
, COUNT( CASE WHEN CT.TYPE = 'BOOK' THEN T.TRANSACTION_ID END ) books
, COUNT( CASE WHEN CT.TYPE = 'DVD' THEN T.TRANSACTION_ID END ) dvds
FROM customer C
INNER JOIN library_card LC ON C.CUSTOMER_ID = LC.CUSTOMER_ID
INNER JOIN transaction T ON LC.LIBRARY_CARD_ID = T.LIBRARY_CARD_ID
INNER JOIN physical_item P ON T.PHYSICAL_ITEM_ID = P.PHYSICAL_ITEM_ID
INNER JOIN catalog_item CT ON P.CATALOG_ITEM_ID = CT.CATALOG_ITEM_ID
GROUP BY
C.CUSTOMER_FIRSTNAME
, C.CUSTOMER_LASTNAME
HAVING
COUNT( CASE WHEN CT.TYPE = 'BOOK' THEN T.TRANSACTION_ID END )
> COUNT( CASE WHEN CT.TYPE = 'DVD' THEN T.TRANSACTION_ID END )
ORDER BY
C.CUSTOMER_FIRSTNAME
, C.CUSTOMER_LASTNAME
;
You can use catalog_item table twice( think of as seperate tables for books and dvds ), and compare by HAVING clause as :
SELECT C.CUSTOMER_FIRSTNAME, C.CUSTOMER_LASTNAME,
COUNT(CT1.CATALOG_ITEM_ID) as "Book Checkout",
COUNT(CT2.CATALOG_ITEM_ID) as "DVD Checkout"
FROM customer C
INNER JOIN library_card LC ON C.CUSTOMER_ID = LC.CUSTOMER_ID
INNER JOIN transaction T ON LC.LIBRARY_CARD_ID = T.LIBRARY_CARD_ID
INNER JOIN physical_item P ON T.PHYSICAL_ITEM_ID = P.PHYSICAL_ITEM_ID
LEFT JOIN catalog_item CT1 ON P.CATALOG_ITEM_ID = CT1.CATALOG_ITEM_ID AND CT1.TYPE = 'BOOK'
LEFT JOIN catalog_item CT2 ON P.CATALOG_ITEM_ID = CT2.CATALOG_ITEM_ID AND CT1.TYPE = 'DVD'
GROUP BY C.CUSTOMER_FIRSTNAME, C.CUSTOMER_LASTNAME
HAVING COUNT(CT1.CATALOG_ITEM_ID) > COUNT(CT2.CATALOG_ITEM_ID)
ORDER BY C.CUSTOMER_FIRSTNAME, C.CUSTOMER_LASTNAME;
CUSTOMER_FIRSTNAME CUSTOMER_LASTNAME Book Checkout DVD Checkout
------------------ ----------------- ------------- -------------
Deena Pilgrim 3 1
Emile Cross 5 2
Please try to remove ,CT1.TYPE, CT2.TYPE on your group by clause.

Converting SQL to LINQ with left join and group by

I have done this query by SQL, and want to translate to LINQ
SELECT
ENT_DESC,
CAT_DESC,
PART_NUM,
PART_DESC,
GROUP_CONCAT(PART_OPTIONS.CODE, CHAR(13)) AS CODE,
PART_OPTIONS.PROMPT AS PROMPT,
PART_OPTIONS.DESCRIPTION AS DESCRIPTION,
PART_OPTIONS.PRICE AS PRICE,
ATTRIBUTE_DATA.NOTE,
ATTRIBUTE_DATA.DESCRIPTION AS ATTR_DESC
FROM ITEM_DATA
LEFT JOIN PART_OPTIONS ON ITEM_DATA.ID = PART_OPTIONS.PART_ID
LEFT JOIN ATTRIBUTE_DATA ON ITEM_DATA.ID = ATTRIBUTE_DATA.PART_ID
GROUP BY PART_OPTIONS.PART_ID
I know how to do this without GROUP_CONCAT,
from c in ITEM_DATA
join a in ATTRIBUTE_DATA on c.ID equals a.PART_ID into at
from a in at.DefaultIfEmpty()
join p in PART_OPTIONS on c.ID equals p.PART_ID into pa
from p in pa.DefaultIfEmpty()
select new {
ENT_DESC = c.ENT_DESC,
CAT_DESC = c.CAT_DESC,
PART_NUM = c.PART_NUM,
PART_DESC = c.PART_DESC,
CODE = p.CODE,
PROMPT = p.PROMPT,
DESCRIPTION = p.DESCRIPTION,
PRICE = p.PRICE,
NOTE = a.NOTE,
ATTR_DESC = a.DESCRIPTION,
}
and also I have done GROUP_CONCAT separately
from c in ITEM_DATA
join a in ATTRIBUTE_DATA on c.ID equals a.PART_ID into at
from a in at.DefaultIfEmpty()
join p in PART_OPTIONS on c.ID equals p.PART_ID into pa
from p in pa.DefaultIfEmpty()
group p by p.PART_ID into ps
select new {
CODE = ps.Select(g=>g.CODE),
}
but after that "c" and "a" are gone and i don"t know how to get access to ITEM_DATA and ATTRIBUTE_DATA tables.

A column in the predicate of the SQL

How can I select custType in the predicate section of the query
I can't do so now because
Error code -1, SQL state 42X04: Column 'CUSTTYPE' is either not in any table in the FROM list or appears within a join specification and is outside the scope of the join specification or appears in a HAVING clause and is not in the GROUP BY list. If this is a CREATE or ALTER TABLE statement then 'CUSTTYPE' is not a column in the target table.
select p.SKU AS GiftID, p.ProductName AS GiftName,
case when sa.Sales >= v.LevelUpAmount then 1 else 2 end AS custType
from products p, campaign ca, SubCategory sc,
VIPLevelUpParam v,
ActiveParam a, customer c,
(select c.CustomerCode, sum(od.NetSales) AS Sales from customer c
INNER JOIN orders o ON (c.CustomerCode = o.CustomerCode)
INNER JOIN order_details od ON (o.OrderCode = od.OrderCode)
group by c.CustomerCode ) sa
where ca.CUSTOMERTYPE = custType AND
c.CustomerCode = 'CUS000001-2013-11-06' AND
p.SubCategoryID = sc.SubCategoryCode AND
p.SKU = ca.GiftID AND
sc.SubCategoryName = 'Gift'AND
v.LevelUpID = a.ActiveID AND
a.TableName = 'VIPLevelUpParam'
group by p.SKU, p.ProductName, sa.Sales, v.LevelUpAmount, custType;
Any one shed some light on this, it would be greatly appreciated!
As per logical query processing where clause is evaluated before select statement that why you're getting CustType column won't be available in where clause.
http://blog.sqlauthority.com/2009/04/06/sql-server-logical-query-processing-phases-order-of-statement-execution/
select * from
(
select p.SKU AS GiftID, p.ProductName AS GiftName,
case when sa.Sales >= v.LevelUpAmount then 1 else 2 end AS custType
from products p, campaign ca, SubCategory sc,
VIPLevelUpParam v,
ActiveParam a, customer c,
(select c.CustomerCode, sum(od.NetSales) AS Sales from customer c
INNER JOIN orders o ON (c.CustomerCode = o.CustomerCode)
INNER JOIN order_details od ON (o.OrderCode = od.OrderCode)
group by c.CustomerCode ) sa
) DT
where DT.CUSTOMERTYPE = DT.custType AND
DT.CustomerCode = 'CUS000001-2013-11-06' AND
DT.SubCategoryID = DT.SubCategoryCode AND
DT.SKU = DT.GiftID AND
DT.SubCategoryName = 'Gift' AND
DT.LevelUpID = DT.ActiveID AND
DT.TableName = 'VIPLevelUpParam'
group by DT.SKU, DT.ProductName, DT.Sales, DT.LevelUpAmount, DT.custType;

Two If selection while a select query

SELECT o.id, o.id as oid, o.id as orderId, o.cid, o.date, o.state,
o.price, o.currency, o.lastChange, o.url AS permalink, o.period,
o.bloggerId, o.bloggerShare, o.offerValidity, o.rebate, o.cid,
o.reason, o.bidReason, o.bidDate, o.bidPeriod, o.rate,
o.lastChange2, o.permalinkDate, o.cancelDate, o.bidValidDate,
o.acceptDate, o.approveDate, o.archived, o.bloggerPrice,
o.customerPrice, o.cancelReason, o.listPrice, o.adFormat,
o.lastPayDate, o.startDate, o.endDate, o.customerBidDate,
o.zoneId, c.campaignStartDate, c.campaignEndDate,
c.type as campaignType, c.test, c.test1, c.special, c.packageId,
c.fixPrice, c.type, c.priceBidding, c.textCreation, o.hiddenField,
o.startDate, p.url as producturlold, p.pressurl, p.companyurl,
p.blogurl, p.mediaurl, p.short,
p.description as productDescription, p.description2, p.image,
c.teaser, c.kind, c.title, mc.country as campaignCountry,
c.minlen, c.productPrice, c.currency as campaignCurrency,
c.productTitle, c.url, c.producturl, c.pressurl, c.companyurl,
c.blogurl, c.mediaurl, c.description, c.image, c.teaser,
c.productReturn, c.testProduct, c.mid as customerId, c.adText,
c.fixAdText, c.requiresBlog, c.bidStop, c.accountingPeriod,
c.actionCodeType, c.actionCodesDescription, ac.code,
ac2.code as massCode, b.title as blogtitle, b.url as bloggerurl,
b.pis as pis, b.uniqueVisitors as uvs, b.pisCounter as pisCounter,
b.uvsCounter as uvsCounter, b.aPI as aPI, b.aUV as aUV,
b.id as blogId, p.title as productTitleOld,
b.lastChange as blogLastChange, b.trRank, r1.rate as orderRate,
r2.Rate as memberRate, b.reviews
FROM rates r1, rates r2, orders o
left join blog b on (o.blogId = b.id)
left join codes ac on (ac.orderId = o.id), campaign c
left join product p on (c.productId = p.id)
left join codes ac2 on (ac2.campaignId = c.id and
c.actionCodeType = 2),
person mc
where o.cid = c.id
and mc.mid = c.mid
and o.id = '223704'
and o.state <> 0
and r1.currency = o.currency
and r2.currency = 'EUR'
and r1.date = FROM_UNIXTIME(o.date, '%Y-%m-%d')
and r2.date = r1.date
I wnat to test if memberRate and orderRate is Null it should continue how can i do that? Any idea?
Tack this on the end should do the trick:
--Within the WHERE clause
AND r2.Rate IS NOT NULL
AND r1.Rate IS NOT NULL
I'm not sure I understand what you are asking, but add and memberRate is not null and orderRate is not null to the end of your query and you will skip all results where either of those two fields are null.