SQL query with 2 counts and 2 left outer joins - sql

Im trying to show all columns from my t1_elem table and join 2 columns in which I use COUNT.
I used query:
SELECT p.*,COUNT(t4_id) as ile_publikacji, COUNT(t7_id) as ile_fitow
FROM t1_elem p
LEFT OUTER JOIN t4_autorzy ON p.t1_id=t4_autorzy.t4_t1_id
LEFT JOIN t7_pliki ON p.t1_id=t7_pliki.t7_t1_id
GROUP BY t1_id
But the results are bad. What I'm doing wrong?

Probably you have multiple matches. As stated, the two counts will be the same. The simplest solution is probably to use distinct:
SELECT p.*, COUNT(DISTINCT t4_id) as ile_publikacji, COUNT(DISTINCT t7_id) as ile_fitow
FROM t1_elem p LEFT JOIn
t4_autorzy
ON p.t1_id = t4_autorzy.t4_t1_id LEFT JOIN
t7_pliki
ON p.t1_id=t7_pliki.t7_t1_id
GROUP BY t1_id

Related

Select and join returning duplicate data

I have some tables that can be accessed here and I would like to get a new table with EntryId from Entry table and ProtocolNumber from JudicialOrder table. For that I'm using this query:
SELECT DISTINCT ET.EntryId, JOA.ProtocolNumber FROM Entry AS ET
LEFT JOIN JudicialOrderAccount AS JOT ON JOT.AccountId = ET.OwnerAccountId
INNER JOIN JudicialOrder AS JOA ON JOA.JudicialOrderId = JOT.JudicialOrderId;
But the ProtocolNumber is duplicated, what could be wrong with my query?
As Kurt said only the combination of ET.EntryId, JOA.ProtocolNumber is unique. You will recognize it if you add an order by.
SELECT DISTINCT ET.EntryId, JOA.ProtocolNumber FROM Entry AS ET
LEFT JOIN JudicialOrderAccount AS JOT ON JOT.AccountId = ET.OwnerAccountId
INNER JOIN JudicialOrder AS JOA ON JOA.JudicialOrderId = JOT.JudicialOrderId
ORDER BY ET.EntryId, JOA.ProtocolNumber;
If you would really like to have unique protocol number you would need to group by ProtocolNumber and wrap EntryId in some string_agg function (depends on your database).
FYI: Your LEFT JOIN - INNER JOIN combination ends up being two INNER JOINs, see

Three tables with two counts with group by

In my query I want total file count and total closed files in the same table.
My first query:
select hi.eksper_id,ef.ad, count(hi.eksper_id) as total_files
from hasar_ihbar as hi
left outer join eksper_firma ef on ef.id=hi.eksper_id
group by hi.eksper_id,ef.ad
My second query:
select ef.id as eksper_id,ef.ad,count(ef.id) closed_files
from hasar_ihbar_rapor hir
left outer join hasar_ihbar hi on hi.id = hir.hasar_ihbar_id
left outer join eksper_firma ef on ef.id = hi.eksper_id
where hir.rapor_tipi = 3 group by ef.id,ef.ad
I want both combined and this is my code:
select ef.id as eksper_id,ef.ad,count(ef.id) closed_files, count(hi.id) AS total_files
from hasar_ihbar_rapor hir
left outer join hasar_ihbar hi on hi.id = hir.hasar_ihbar_id
left outer join eksper_firma ef on ef.id = hi.eksper_id
where hir.rapor_tipi = 3 group by ef.id,ef.ad
I don't know what I did wrong. Thanks for your help.
The double joins effect your counts since there are more rows.
A better way to combine both counts is to create a query that has two subqueries for each count.
SELECT id,
(SELECT COUNT(*)...) total_files,
(SELECT COUNT(*)...) closed_files
FROM ...

Left Outer Join Without Duplicate Rows

After a lot of searching I could not solve my problem. I have the following tables:
I want to select all records from my 'product' table. but I have a problem. I got multiple rows from 'product' table when I execute the following query:
SELECT dbo.product.id, dbo.product.name, dbo.product_price.value
dbo.product_barcode.barcode
FROM dbo.product LEFT OUTER JOIN
dbo.product_price ON dbo.product.id = dbo.product_price.product_id LEFT OUTER JOIN
dbo.product_barcode ON dbo.product.id = dbo.product_barcode.product_id
My problem was solved with the following query:
SELECT dbo.product.id, dbo.product.name, dbo.product_price.value
dbo.product_barcode.barcode
FROM dbo.product LEFT OUTER JOIN
dbo.product_price ON dbo.product.id = dbo.product_price.product_id LEFT OUTER JOIN
dbo.product_barcode ON dbo.product.id = dbo.product_barcode.product_id
WHERE (dbo.product_price.id IN
(SELECT MIN(id) AS minPriceID
FROM dbo.product_price AS product_price_1
GROUP BY product_id)) AND (dbo.product_barcode.id IN
(SELECT MIN(id) AS Expr1
FROM dbo.product_barcode AS product_barcode_1
GROUP BY product_id))
Now I have just one problem. if the 'product_price' table or 'product_barcode' table does not have any record, No records will be returned. I mean if no similar record is found in 'product_price' or 'product_barcode' table, we will not have any record. while we should have records from the 'product' table with null columns of other tables.
Please help me Thanks.
I think the problem is that the conditions are in the WHERE clause - try moving the conditions from the WHERE clause and into each join:
SELECT dbo.product.id, dbo.product.name, dbo.product_price.value,
dbo.product_barcode.barcode
FROM dbo.product
LEFT OUTER JOIN dbo.product_price ON dbo.product.id = dbo.product_price.product_id
--moved from WHERE clause
AND dbo.product_price.id IN (SELECT MIN(id) AS minPriceID FROM dbo.product_price AS product_price_1 GROUP BY product_id)
LEFT OUTER JOIN dbo.product_barcode ON dbo.product.id = dbo.product_barcode.product_id
--moved from WHERE clause
AND dbo.product_barcode.id IN (SELECT MIN(id) AS Expr1 FROM dbo.product_barcode AS product_barcode_1 GROUP BY product_id)
SELECT dbo.product.id, dbo.product.name, MIN(dbo.product_price.value),MIN( dbo.product_barcode.barcode)
FROM dbo.product
LEFT OUTER JOIN dbo.product_price ON dbo.product.id = dbo.product_price.product_id
LEFT OUTER JOIN dbo.product_barcode ON dbo.product.id = dbo.product_barcode.product_id
GROUP BY dbo.product.id, dbo.product.name
While the above query should achieve your desired results - one entry for product with the minimun product_price (if one exist) and minimum product_barcode (if one exist).
I only assumed you wanted this based on the query you were writing. You need to spend more time thinking about the question you are trying to answer.
Joining will multiply your results if more than one entry per join key is present in one of the tables.
Just remember this diagram:
When you are calling LEFT JOIN and applying filtering like in the second picture from the top left, you will get only items belonging to the A table.
I want to select all records from my 'product' table. but I have a problem. I got multiple rows from 'product' table when I execute the following query:
Can you try calling DISTINCT after SELECT, like this:
SELECT DISTINCT dbo.product.id, dbo.product.name, dbo.product_price.value
dbo.product_barcode.barcode
...

use Inner Join in SQL

I want to join two tables and then I want to join this result with another table
but it doesn't work
select * from
(
(select SeId,FLName,Company from Sellers) s
inner join
(select SeId,BIId from BuyInvoices) b
on s.SeId=b.SeId
) Y
inner join
(select * from BuyPayments) X
on Y.BIId=X.BIId
thanks
In most databases, your syntax isn't going to work. Although parentheses are allowed in the FROM clause, they don't get their own table aliases.
You can simplify the JOIN. This is a simpler way to write the logic:
select s.SeId, s.FLName, s.Company, bp.*
from Sellers s inner join
BuyInvoices b
on s.SeId = b.SeId inner join
BuyPayments bp
on bp.BIId = b.BIId;

Left outer join and group by issue

I wrote a query. this query sum fields from 2 different table. And grouped by main table id field. But second left outer join is not grouped and giving me different results.
SELECT s.*,
f.firma_adi,
sum(sd.fiyat) AS konak,
sum(ss.fiyat) AS sponsor
FROM fuar_sozlesme1 s
INNER JOIN fuar_firma_2012 f
ON ( s.cari = f.cari )
LEFT OUTER JOIN fuar_sozlesme1_detay sd
ON ( sd.sozlesme_id = s.id )
LEFT OUTER JOIN fuar_sozlesme1_sponsor ss
ON ( ss.sozlesme_id = s.id )
GROUP BY s.id
ORDER BY s.id DESC
I know, it is really complicated but I'm stucking on this issue.
My question is: why second left outer join is not correctly sum of field . If I remove second left outer join or first, everything is normal.
The problem is that you have multiple dimensions on your data, and the number of rows is multiplying beyond what you expect. I would suggest that you run the query for one id, without the group by, to see what rows the join is producing.
One way to fix this is by using correlated subqueries:
select s.*, f.firma_adi,
(select SUM(sd.fiyat)
from fuar_sozlesme1_detay fd
where sd.sozlesme_id = s.id
) as konak,
(select SUM(ss.fiyat)
from fuar_sozlesme1_sponsor ss
where (ss.sozlesme_id = s.id)
) as sponsor
from fuar_sozlesme1 s inner join
fuar_firma_2012 f
on (s.cari = f.cari)
order by s.id DESC
By the way, you appear to by using MySQL (because your query is not parsable in any other dialect). You should tag your questions with the version of the database you are using.