SQL Two result from one column in 2 columns - sql

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....

Related

Sum from the different tables Sql server

I have couple of tables which stores amount and I want to group by and get sum - reason for the mutiple tables are nhibernate descriminators.
I am using Union all and works but query is very big.
I am using following query
SELECT CustomerAccountNumber,
vc.CustomerName,
SUM(PermAmount) AS PermAmount,
SUM(FreetextAmount) AS FreetextAmount,
(SUM(PermAmount) + SUM(FreetextAmount)) AS TotalAmountByCustomer
FROM
(
SELECT pp.CustomerAccountNumber,
pl.Amount AS PermAmount,
0 AS FreetextAmount
FROM dbo.PermanentPlacementTransactionLine pl
INNER JOIN dbo.TransactionLine tl ON pl.TransactionLineId = tl.Id
INNER JOIN dbo.PermanentPlacement pp ON pl.PermanentPlacementId = pp.Id
WHERE tl.CurrentStatus = 1
GROUP BY pp.CustomerAccountNumber,
pl.Amount,
tl.Id
UNION ALL
SELECT ft.CustomerAccountNumber,
0 AS PermAmount,
ft.Amount AS FreetextAmount
FROM dbo.FreeTextTransactionLine fttl
INNER JOIN dbo.TransactionLine tl ON fttl.TransactionLineId = tl.Id
INNER JOIN dbo.[FreeText] ft ON fttl.FreeTextId = ft.Id
WHERE tl.CurrentStatus = 1
GROUP BY ft.CustomerAccountNumber,
ft.Amount,
tl.Id
) WIPSummary
INNER JOIN dbo.vw_Customer vc ON WIPSummary.CustomerAccountNumber = vc.CustomerAccount
GROUP BY CustomerAccountNumber,
vc.CustomerName;
is there any elegant way of displaying amount in separate columns ?
I can use partition by if it was same table and want to display row by row.
Try these query, is easy to understand and probably faster than yours.
I assume that the values are unique in your view
WITH cte_a
AS (SELECT pp.customeraccountnumber
,Sum(pl.amount) AS PermAmount
,0 AS FreetextAmount
FROM dbo.permanentplacementtransactionline pl
INNER JOIN dbo.transactionline tl
ON pl.transactionlineid = tl.id
INNER JOIN dbo.permanentplacement pp
ON pl.permanentplacementid = pp.id
WHERE tl.currentstatus = 1
GROUP BY pp.customeraccountnumber),
cte_b
AS (SELECT ft.customeraccountnumber
,0 AS PermAmount
,Sum(ft.amount) AS FreetextAmount
FROM dbo.freetexttransactionline fttl
INNER JOIN dbo.transactionline tl
ON fttl.transactionlineid = tl.id
INNER JOIN dbo.[freetext] ft
ON fttl.freetextid = ft.id
WHERE tl.currentstatus = 1
GROUP BY ft.customeraccountnumber)
SELECT vc.customeraccountnumber
,vc.customername
,Isnull(A.permamount, 0) AS PermAmount
,Isnull(B.freetextamount, 0) AS FreetextAmount
,Isnull(A.permamount, 0)
+ Isnull(B.freetextamount, 0) AS TotalAmountByCustomer
FROM dbo.vw_customer vc
LEFT JOIN cte_a a
ON vc.customeraccount = A.customeraccountnumber
LEFT JOIN cte_b b
ON vc.customeraccount = A.customeraccountnumber
if no table structures and sample data, that is the best I can do to help you.

Calculate Grouped Average Percentage Using SQL

I need the last column AvgRecordCount to be the average of every two columns; see the first image for an example...
Any suggestions?
SELECT l.AltName,
CASE
WHEN i.LabelTypeID = 1 THEN 'Generic'
WHEN i.LabelTypeID = 2 THEN 'Brand'
END AS LabelType,
COUNT(i.LabelTypeID) as RecordCount
FROM [RxTransaction] rxt
INNER JOIN Dimension.Item i
ON rxt.DispensedItemID = i.ItemID AND
rxt.LocationID = i.LocationID
INNER JOIN Dimension.Location l
ON rxt.LocationID = l.LocationId
WHERE (i.LabelTypeID = 1 OR i.LabelTypeID = 2) AND
rxt.DateFilled BETWEEN '12/1/2014' AND '12/31/2014'
GROUP BY i.LabelTypeID, l.AltName
I'd like to see results like the items in this table, notice the new column percentage average across the two rows, generic/brand sets.
Image shows the SQL and current results, I want a new column that has each 2 rows percentage over each other.
I solved this by writing select statements for each of the calculated fields I needed... see below.
SELECT L.AltName, L.LocationId, COUNT(A.LabelTypeID) As TotalRecords,
(SELECT COUNT(i.LabelTypeID)
FROM [IntellectRX-DataWarehouse].[Fact].[RxTransaction] rxt
INNER JOIN Dimension.Item i on rxt.DispensedItemID = i.ItemID AND rxt.LocationID = i.LocationID
WHERE i.LabelTypeID = 1 AND i.LocationID = L.LocationId AND
rxt.DateFilled between '12/1/2014' and '12/31/2014') As GenericTotal,
100
*
(SELECT COUNT(i.LabelTypeID)
FROM [IntellectRX-DataWarehouse].[Fact].[RxTransaction] rxt
INNER JOIN Dimension.Item i on rxt.DispensedItemID = i.ItemID AND rxt.LocationID = i.LocationID
WHERE i.LabelTypeID = 1 AND i.LocationID = L.LocationId AND
rxt.DateFilled between '12/1/2014' and '12/31/2014')
/
(SELECT COUNT(i.LabelTypeID)
FROM [IntellectRX-DataWarehouse].[Fact].[RxTransaction] rxt
INNER JOIN Dimension.Item i on rxt.DispensedItemID = i.ItemID AND rxt.LocationID = i.LocationID
WHERE (i.LabelTypeID = 1 OR i.LabelTypeID = 2) AND i.LocationID = L.LocationId AND
rxt.DateFilled between '12/1/2014' and '12/31/2014') As PercentAvg
FROM [IntellectRX-DataWarehouse].[Fact].[RxTransaction] B
INNER JOIN Dimension.Item A on B.DispensedItemID = A.ItemID AND B.LocationID = A.LocationID
INNER JOIN Dimension.Location L on B.LocationID = L.LocationId
WHERE B.DateFilled between '12/1/2014' and '12/31/2014'
Group by L.AltName, L.LocationId
order by PercentAvg
You need to group by with the exact CASE statement you have used in your select statement , something like....
SELECT l.AltName,
CASE
WHEN i.LabelTypeID = 1 THEN 'Generic'
WHEN i.LabelTypeID = 2 THEN 'Brand'
END AS LabelType,
COUNT(i.LabelTypeID) as RecordCount
FROM [RxTransaction] rxt
INNER JOIN Dimension.Item i
ON rxt.DispensedItemID = i.ItemID AND
rxt.LocationID = i.LocationID
INNER JOIN Dimension.Location l
ON rxt.LocationID = l.LocationId
WHERE (i.LabelTypeID = 1 OR i.LabelTypeID = 2) AND
rxt.DateFilled BETWEEN '12/1/2014' AND '12/31/2014'
GROUP BY l.AltName,
CASE
WHEN i.LabelTypeID = 1 THEN 'Generic'
WHEN i.LabelTypeID = 2 THEN 'Brand'
END

Informix: Query merge

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

Cannot perform an aggregate function on an expression containing an aggregate or a subquery sql server 2012

I am performing a query and its showing an error Cannot perform an aggregate function on an expression containing an aggregate or a subquery.
the query is
SELECT
tbl_Product.ID,
tbl_Product.ArticleID,
tbl_Product.Title,
tbl_Product.Description,
tbl_Product.Price,
tbl_ProductType.Name,
tbl_Status.StatusName,
tbl_VisibilityStatus.VisibilityStatus,
MAX(
CASE
WHEN tbl_RelatedProduct.TypeOfRelation = 1 THEN 'Bundle'
WHEN tbl_Product.ID IN
(
select tbl_RelatedProduct.Product2ID
from tbl_RelatedProduct
where tbl_RelatedProduct.Product1ID=9 and tbl_RelatedProduct.TypeOfRelation=1) THEN 'Bundle'
END
) 'Bundle',
MAX(
CASE
WHEN tbl_RelatedProduct.TypeOfRelation = 2 THEN 'Follower' END) 'Follower',
MAX(
CASE
WHEN tbl_RelatedProduct.TypeOfRelation = 3 THEN 'Related' END) 'Related'
FROM
tbl_Product inner JOIN
tbl_ProductType ON tbl_Product.ProductTypeId = tbl_ProductType.ID Inner JOIN
tbl_Status ON tbl_Product.StatusID = tbl_Status.ID Inner JOIN
tbl_VisibilityStatus ON tbl_Product.VisibilityID = tbl_VisibilityStatus.ID
left JOIN tbl_RelatedProduct ON tbl_Product.ID = tbl_RelatedProduct.Product1ID
group by
tbl_Product.ID,
tbl_Product.ArticleID,
tbl_Product.Title,
tbl_Product.Description,
tbl_Product.Price,
tbl_ProductType.Name,
tbl_Status.StatusName,
tbl_VisibilityStatus.VisibilityStatus
order by tbl_Product.Title
ANyone know how to help on this...plsss
The below line is causing an issue:
WHEN tbl_Product.ID IN
(
select tbl_RelatedProduct.Product2ID
from tbl_RelatedProduct
where tbl_RelatedProduct.Product1ID=9 and tbl_RelatedProduct.TypeOfRelation=1) THEN 'Bundle'
END
) 'Bundle',
You are using MAX with CASE and one of the statements within CASE uses a subquery, which is causing the error. You might want to consider using joins instead of subqueries to implement this.
SELECT tbl_Product.ID,tbl_Product.ArticleID,tbl_Product.Title,tbl_Product.Description,tbl_Product.Price,tbl_ProductType.Name,tbl_Status.StatusName, tbl_VisibilityStatus.VisibilityStatus,
Case when ((select count(1) from tbl_RelatedProduct where tbl_RelatedProduct.TypeOfRelation = 1 and tbl_RelatedProduct.Product1ID = tbl_Product.Id) > 0) then 1
when ((select count(1) from tbl_RelatedProduct where tbl_RelatedProduct.TypeOfRelation = 1 and tbl_RelatedProduct.Product2ID = tbl_Product.Id) > 0) then 1
else 0 end as Bundle,
(select count(1) from tbl_RelatedProduct where tbl_RelatedProduct.TypeOfRelation = 2 and tbl_RelatedProduct.Product1ID = tbl_Product.Id) as Follower,
(select count(1) from tbl_RelatedProduct where tbl_RelatedProduct.TypeOfRelation = 3 and tbl_RelatedProduct.Product1ID = tbl_Product.Id) as Related
FROM tbl_Product
inner JOIN
tbl_ProductType ON tbl_Product.ProductTypeId = tbl_ProductType.ID Inner JOIN
tbl_Status ON tbl_Product.StatusID = tbl_Status.ID
Inner JOIN
tbl_VisibilityStatus ON tbl_Product.VisibilityID = tbl_VisibilityStatus.ID
Its resolved with this query :)
I think I see what you are trying to do, and it is a bit strange. I would output this all as a single column, and lose the MAX aggregate as follows:
SELECT
p.ID,
p.ArticleID,
p.Title,
p.Description,
p.Price,
pt.Name,
s.StatusName,
v.VisibilityStatus,
CASE
WHEN rp.TypeOfRelation = 1 OR (rp2.Product1ID = 9 AND rp2.TypeOfRelation = 1)
THEN 'Bundle'
WHEN rp.TypeOfRelation = 2
THEN 'Follower'
WHEN rp.TypeOfRelation = 3
THEN 'Related'
ELSE Null
END AS Relation
FROM
tbl_Product p
INNER JOIN tbl_ProductType pt
ON p.ProductTypeId = pt.ID
INNER JOIN tbl_Status s
ON p.StatusID = s.ID
INNER JOIN tbl_VisibilityStatus v
ON p.VisibilityID = v.ID
LEFT JOIN tbl_RelatedProduct rp
ON p.ID = rp.Product1ID
LEFT JOIN tbl_RelatedProduct rp2
ON p.ID = rp2.Product2ID
ORDER BY p.Title
If you would still like to have them in separate columns, just break up the CASE statement as follows:
SELECT
p.ID,
p.ArticleID,
p.Title,
p.Description,
p.Price,
pt.Name,
s.StatusName,
v.VisibilityStatus,
CASE
WHEN rp.TypeOfRelation = 1 OR (rp2.Product1ID = 9 AND rp2.TypeOfRelation = 1)
THEN 'Bundle'
ELSE Null
END AS Bundle,
CASE
WHEN rp.TypeOfRelation = 2
THEN 'Follower'
ELSE Null
END AS Follower,
CASE
WHEN rp.TypeOfRelation = 3
THEN 'Related'
ELSE Null
END AS Related
FROM
tbl_Product p
INNER JOIN tbl_ProductType pt
ON p.ProductTypeId = pt.ID
INNER JOIN tbl_Status s
ON p.StatusID = s.ID
INNER JOIN tbl_VisibilityStatus v
ON p.VisibilityID = v.ID
LEFT JOIN tbl_RelatedProduct rp
ON p.ID = rp.Product1ID
LEFT JOIN tbl_RelatedProduct rp2
ON p.ID = rp2.Product2ID
ORDER BY p.Title

Take query true when one clause is false

This is my query
SELECT pl.NAME
,pl.id_product
,pl.link_rewrite
,i.id_image
,ar.id_auctions_rutcom
,ar.actual_bid_price
,ar.start_price
,ar.min_price
,ar.buy_now_price
,ar.finish_date
FROM ps_image i
,ps_auctions_rutcom ar
,ps_product_lang pl
WHERE ar.finish_date > '2013-07-26 11:18:15'
AND ar.start_date < '2013-07-26 11:18:15'
AND ar.active = 1
AND ar.finish = 0
AND pl.id_product = ar.id_product
AND i.id_product = ar.id_product
AND i.cover = 1
AND pl.id_lang = 6
I have problem when on table ps_image is no image where i.id_product = ar.id_product my query return false. How to change query to set true?
You should learn about JOIN. Google it.
Your query is equivalent to INNER JOIN:
SELECT
pl.name, pl.id_product, pl.link_rewrite, i.id_image, ar.id_auctions_rutcom,
ar.actual_bid_price, ar.start_price, ar.min_price, ar.buy_now_price, ar.finish_date
FROM ps_auctions_rutcom ar
INNER JOIN ps_product_lang pl
ON pl.id_product = ar.id_product
AND pl.id_lang = 6
INNER JOIN ps_image i
ON i.id_product = ar.id_product
AND i.cover = 1
WHERE ar.finish_date > '2013-07-26 11:18:15'
AND ar.start_date < '2013-07-26 11:18:15'
AND ar.active = 1
AND ar.finish = 0
With an INNER JOIN, if there is no matching row in the related table, the row is omitted from the result set.
Now, you should use an OUTER JOIN, in which case the row is still in the result set and the missing information is set to NULL.
SELECT
pl.name, pl.id_product, pl.link_rewrite, i.id_image, ar.id_auctions_rutcom,
ar.actual_bid_price, ar.start_price, ar.min_price, ar.buy_now_price, ar.finish_date
FROM ps_auctions_rutcom ar
INNER JOIN ps_product_lang pl
ON pl.id_product = ar.id_product
AND pl.id_lang = 6
LEFT OUTER JOIN ps_image i
ON i.id_product = ar.id_product
AND i.cover = 1
WHERE ar.finish_date > '2013-07-26 11:18:15'
AND ar.start_date < '2013-07-26 11:18:15'
AND ar.active = 1
AND ar.finish = 0
You can add in your query to make sure ps_image has not null
Where i.id_product IS NOT NULL
You should separate your joins from your filters, then use a left join to provide all the results
regardless of whether an image exists
FROM ps_auctions_rutcom ar
left join
ps_image i on i.id_product = ar.id_product
and i.cover = 1
left join
ps_product_lang pl on pl.id_product = ar.id_product
and pl.id_lang = 6
WHERE ....