I'm coming across an issue where when I write a query as so:
SELECT a.v, b.w, c.x, d.y, e.z
FROM a
JOIN b
on a.id = b.id
LEFT JOIN c
on a.id = c.id
LEFT JOIN d
on b.code=d.code
JOIN e
on a.n = e.n
WHERE
a.zone = 10
WITH (nolock)
I get several hundred results, but when I modify it to this:
SELECT a.v, b.w, c.x, d.y, e.z
FROM a
JOIN b
on a.id = b.id
LEFT JOIN c
on a.id = c.id AND c.n = 0
LEFT JOIN d
on b.code=d.code AND d.n = 0
JOIN e
on a.n = e.n
WHERE
a.zone = 10
WITH (nolock)
I get zero results.
From my understanding of SQL and left joins, I feel that getting any results with the first query means I should definitely get at least one result with the second, if only one where fields from c and d are null. Does PROGRESS implement outer joins in an unusual manner?
You might want to figure out what the c.n and d.n values are. Try something like this to figure out where your starting point is.
SELECT c.n, d.n, count(*)
FROM a
JOIN b
on a.id = b.id
LEFT JOIN c
on a.id = c.id
LEFT JOIN d
on b.code=d.code
JOIN e
on a.n = e.n
WHERE
a.zone = 10
group by c.n, d.n
Then you can adjust your query based on the result
Related
I have a View that has a column named 'Reference' and a column named 'RateeId' and collects and computes data from another table and used SUM function to get its TotalScores. However, when I input the same RateeId but different Reference, the SUM calculates both and displays the same Scores.
This is what I have tried so far.
This is my script for my view:
select e.Id, b.Name, f.SiteName, e.Reference, e.Amount, e.DateTransaction, SUM(a.Score * (c.Weight / 100) * (d.Weight / 100)) as TotalScore, a.Status, a.CreatedByUserId
from prs_rate as a
left outer join prs_ratee as b on a.RateeId = b.Id
left outer join prs_kpi as c on a.KpiId = c.Id
left outer join prs_group as d on c.GroupId = d.Id
left outer join prs_totalratee as e on a.RateeId = e.RateeId
left outer join core_vSiteInfo as f on e.SiteCatered = f.siteCode
group by b.Name, a.Status, a.CreatedByUserId, e.Reference, e.Amount, e.DateTransaction, f.SiteName, e.Id
This is what it returned:
This is the View prs_vMainKPI. The result of the above script.
Please add order by clause and try again...
select e.Id, b.Name, f.SiteName, e.Reference, e.Amount, e.DateTransaction, SUM(a.Score * (c.Weight / 100) * (d.Weight / 100)) as TotalScore, a.Status, a.CreatedByUserId
from prs_rate as a
left outer join prs_ratee as b on a.RateeId = b.Id
left outer join prs_kpi as c on a.KpiId = c.Id
left outer join prs_group as d on c.GroupId = d.Id
left outer join prs_totalratee as e on a.RateeId = e.RateeId
left outer join core_vSiteInfo as f on e.SiteCatered = f.siteCode
group by e.Id, e.Reference, b.Name, a.Status, a.CreatedByUserId, e.Amount, e.DateTransaction, f.SiteName
order by e.Id, e.Reference
i'm trying to get all the elements on the table B_ARTICULOS and make some calculations joining other tables (where some elements of B_ARTICULOS are not present) and I know I have to use a left join for that but I dont know what i'm doing wrong.
With this query I dont get every B_ARTICULOS, only those that are listed on the other tables
SELECT a.id, a.nombre,
CASE WHEN a.id IN dc.id_articulo THEN dc.cantidad ELSE 0 END CANTIDAD_COMPRAS,
CASE WHEN a.id IN dc.id_articulo THEN dc.cantidad * a.costo ELSE 0 END MONTO_COMPRAS,
CASE WHEN a.id IN dv.id_articulo THEN dv.cantidad ELSE 0 END CANTIDAD_VENTAS,
CASE WHEN a.id IN dv.id_articulo THEN dv.cantidad * a.precio ELSE 0 END MONTO_VENTAS
FROM B_ARTICULOS a
LEFT JOIN B_DETALLE_COMPRAS dc ON a.id = dc.id_articulo
JOIN B_COMPRAS c ON dc.id_compra = c.id
JOIN B_DETALLE_VENTAS dv ON dv.id_articulo = a.id
JOIN B_VENTAS v ON v.id = dv.id_venta
WHERE a.id IS NOT NULL;
The only explanation which I can see here is that you should be left joining to some of those other tables, beyond the second B_DETALLE_COMPRAS table. Assuming you would use left joins everywhere:
SELECT
a.id,
a.nombre,
CASE WHEN a.id IN dc.id_articulo THEN dc.cantidad ELSE 0 END CANTIDAD_COMPRAS,
CASE WHEN a.id IN dc.id_articulo THEN dc.cantidad * a.costo ELSE 0 END MONTO_COMPRAS,
CASE WHEN a.id IN dv.id_articulo THEN dv.cantidad ELSE 0 END CANTIDAD_VENTAS,
CASE WHEN a.id IN dv.id_articulo THEN dv.cantidad * a.precio ELSE 0 END MONTO_VENTAS
FROM B_ARTICULOS a
LEFT JOIN B_DETALLE_COMPRAS dc ON a.id = dc.id_articulo
LEFT JOIN B_COMPRAS c ON dc.id_compra = c.id
LEFT JOIN B_DETALLE_VENTAS dv ON dv.id_articulo = a.id
LEFT JOIN B_VENTAS v ON v.id = dv.id_venta
WHERE a.id IS NOT NULL;
You have to use left join too for other tables, like so:
...
FROM B_ARTICULOS a
LEFT JOIN B_DETALLE_COMPRAS dc ON a.id = dc.id_articulo
LEFT JOIN B_COMPRAS c ON dc.id_compra = c.id
LEFT JOIN B_DETALLE_VENTAS dv ON dv.id_articulo = a.id
LEFT JOIN B_VENTAS v ON v.id = dv.id_venta
...
Personally, I make subqueries for all the related tables that will be left joined to the main table. I grouped those tables then left join them to the main, like so:
...
FROM B_ARTICULOS a
LEFT JOIN (
SELECT dc.*
FROM B_DETALLE_COMPRAS dc
JOIN B_COMPRAS c ON dc.id_compra = c.id
) dc on a.id = dc.id_articulo
LEFT JOIN (
SELECT dv.*
FROM B_DETALLE_VENTAS dv
JOIN B_VENTAS v ON v.id = dv.id_venta
) dv ON dv.id_articulo = a.id
...
I am using SQL query but query resulted 12 lines, needs to be 3 lines; I can't figure it out.
Not working query:
SELECT g.*
,c.TxtFobFiyati
,C.TxtTalepETeslimTarihi
,c.TslParaBirimi
,c.TxtFiyat
,C.TslDepoKodu
,c.TslOlcuBirimi AS 'Olcu'
,j.TxtAmbalajDara
,j.TxtPaletDara
,g.TxtAdet AS 'ambalajAdet'
,g.TxtPaletSayisi AS 'paletSayisi'
,j.TxtAmbalajAdi
,J.TxtAmbalajNetKG
,j.TxtBoxGrossWeight
,C.TxtAciklama AS 'KalemAciklama'
,G.TxtAciklama AS 'KalemAciklama2'
,g.TxtPaletUstu AS 'PaletUstu'
,g.TxtPaletSayisi AS 'PaletSayisi'
,c.TxtUrunAdiEng AS 'UrunAdi_Ingilizce'
,C.TxtFobFiyati AS 'FobFiyati'
,j.TslPaletTipi AS 'PaletTipi'
,j.TxtPaletDara AS 'PaletDara'
FROM E_KT_SAS_Form A
LEFT JOIN E_KT_SAS_Form_DtyUrunler2 B
ON A.ID = B.FORMID
LEFT JOIN E_KT_SAS_FrmSipUrunEkle C
ON B.DOCUMENTID = C.ID
LEFT JOIN E_KT_SAS_Form_DtyTeyitEdilen2 D
ON A.ID = D.FORMID
LEFT JOIN E_KT_SAS_FrmUretimTarihiEkle E
ON D.DOCUMENTID = E.ID
AND E.TslUrun = C.TslUrunKodu
LEFT JOIN E_KT_SAS_Form_DtySevkiyatlar F
ON A.ID = F.FORMID
LEFT JOIN E_KT_SAS_FrmSevkiyatEkle G
ON F.DOCUMENTID = G.ID
LEFT JOIN E_KT_SAS_FrmSipUrunEkle_DtyAmbalajlama H
ON C.ID = H.FORMID
LEFT JOIN E_KT_SAS_FrmUrunAmbalajlama J
ON H.DOCUMENTID = J.ID
WHERE E.TslOnay_TEXT = 'Evet'
AND C.TslUrunKodu = G.TslUrun
AND A.ID = 11682
Not working result
Correct result table
Step1) Start count with the driver table i.e. the one you have alias as 'A'. Check the count if you get 3. Continue.
Repeat step 1 with each new join and see where your count blows up to 12. That is your troubling join. Comment it out if possible and continue with joins. If you cannot do successive joins then find best solution to bring count back down to 3.
If your sure of your where clause great; else start without it too. If count is more than 3. Pop it back in.
select count(1)
FROM E_KT_SAS_Form A
LEFT JOIN E_KT_SAS_Form_DtyUrunler2 B ON A.ID = B.FORMID
LEFT JOIN E_KT_SAS_FrmSipUrunEkle C ON B.DOCUMENTID = C.ID
LEFT JOIN E_KT_SAS_Form_DtyTeyitEdilen2 D ON A.ID = D.FORMID
LEFT JOIN E_KT_SAS_FrmUretimTarihiEkle E ON D.DOCUMENTID = E.ID
AND E.TslUrun = C.TslUrunKodu
LEFT JOIN E_KT_SAS_Form_DtySevkiyatlar F ON A.ID = F.FORMID
LEFT JOIN E_KT_SAS_FrmSevkiyatEkle G ON F.DOCUMENTID = G.ID
LEFT JOIN E_KT_SAS_FrmSipUrunEkle_DtyAmbalajlama H ON C.ID = H.FORMID
LEFT JOIN E_KT_SAS_FrmUrunAmbalajlama J ON H.DOCUMENTID = J.ID
WHERE E.TslOnay_TEXT = 'Evet' AND C.TslUrunKodu = G.TslUrun AND A.ID = 11682
Here is my request
SELECT j.* ,
c.name as client_name ,
s.name as supplier_name,
s.ID as supplier_id ,
mt.* ,
SUM(pb.require_followup) as nb_followup,
SUM(ws.worked_time) as hours_on_job,
SUM(iv.total) as total_price,
SUM(iv.hour_expected) as hours_planned,
j.ID as ID
FROM $wpdb->posts j
LEFT JOIN ".Job::$META_TABLE." mt ON mt.post_id = j.ID
LEFT JOIN ".Job::$LINK_TABLE_JOB_CONTACT." l1 ON l1.job_id = j.ID
LEFT JOIN ".Contact::$TABLE_NAME." c ON c.ID = l1.contact_id
LEFT JOIN ".Supplier::$TABLE_NAME." s ON s.ID = c.supplier_id
LEFT JOIN ".Problem::$TABLE_NAME." pb ON pb.job_id = j.ID
LEFT JOIN ".Worksheet::$TABLE_NAME." ws ON ws.job_id = j.ID
LEFT JOIN ".Invoice::$TABLE_NAME." iv ON iv.job_id = j.ID
WHERE j.post_status = 'publish'
AND j.post_type = 'job'
".implode(' ',$where_condition)."
GROUP BY j.ID
ORDER BY j.post_date DESC
the Problem is that result for SUM is wrong when I LEFT JOIN other table.
The row 53 for example give 105 for nb_followup instead of 1
Where this request return the right result simply by removing the last 2 LEFT JOIN : LEFT JOIN ".Worksheet::$TABLE_NAME." ws ON ws.job_id = j.ID and
LEFT JOIN ".Invoice::$TABLE_NAME." iv ON iv.job_id = j.ID
SELECT j.* ,
c.name as client_name ,
s.name as supplier_name,
s.ID as supplier_id ,
mt.* ,
SUM(pb.require_followup) as nb_followup,
j.ID as ID
FROM $wpdb->posts j
LEFT JOIN ".Job::$META_TABLE." mt ON mt.post_id = j.ID
LEFT JOIN ".Job::$LINK_TABLE_JOB_CONTACT." l1 ON l1.job_id = j.ID
LEFT JOIN ".Contact::$TABLE_NAME." c ON c.ID = l1.contact_id
LEFT JOIN ".Supplier::$TABLE_NAME." s ON s.ID = c.supplier_id
LEFT JOIN ".Problem::$TABLE_NAME." pb ON pb.job_id = j.ID
WHERE j.post_status = 'publish'
AND j.post_type = 'job'
".implode(' ',$where_condition)."
GROUP BY j.ID
ORDER BY j.post_date DESC
Also removing only LEFT JOIN ".Invoice::$TABLE_NAME." iv ON iv.job_id = j.ID will give 15 as result for the row 53
To resume
Full request give 105 -> wrong should be 1
removing the last join give 15 -> wrong should be 1
removing the last 2 join give 1 -> Correct
You need to calculate the SUM()s BEFORE you join, otherwise the rows multiply because of the joins and this in turn leads to errors in summation. e.g.
SELECT
j.ID as ID
, pb.nb_followup
FROM $wpdb->posts j
LEFT JOIN (select pb.job_id, SUM(pb.require_followup) as nb_followup from ".Problem::$TABLE_NAME." pb GROUP BY pb.job_id) pb ON pb.job_id = j.ID
The other problem you are facing is that MySQL permits "lazy syntax" for group by. Don't use this lazy syntax or you will get unexpected error/bugs. It is very simple to avoid, REPEAT every column of the select clause in the group by clause UNLESS the column is using an aggregate function such as SUM(), COUNT(), MIN(), MAX() and so on.e.g.
select a.col1, b.col2, c.col3 , sum(d.col4)
from a
inner join b on a.id = b.aid
inner join c on b.id = c.bid
inner join d on c.id = d.cid
group by a.col1, b.col2, c.col3
Its my second day with MS Access, i am trying to update an existing application.
And this includes updating some queries. I never knew it was going to be so complex. the parenthesis issue in Access is really disturbing and i hit the wall, i get the "syntax error" error. My SQL query is something like this :
Select ….(Something)
Into …. (Some Table)
From A
Inner join B on A.ID=B.ID
LEFT OUTER JOIN STAR as C on C.ID = A.ID
AND C.Data = ’DEMO1’
AND C.POS= ’POS1’
LEFT OUTER JOIN STAR as D on D.ID = A.ID
AND D.Data = ’DEMO2’
AND D.POS= ‘POS2’
LEFT OUTER JOIN STAR as E on E.ID = A.ID
AND E.Data = ’DEMO3’
AND E.POS= ‘POS3’
And in access, its equivalent that i am trying is :
Select ….
Into ….
From (((A
Inner join B on A.ID=B.ID)
LEFT OUTER JOIN STAR as C (on C.ID = A.ID
AND C.Data = ’DEMO1’
AND C.POS= ’POS1’)
LEFT OUTER JOIN STAR as D (on D.ID = A.ID
AND D.Data = ’DEMO2’
AND D.POS= ‘POS2’)
LEFT OUTER JOIN STAR as E on E.ID = A.ID
AND E.Data = ’DEMO3’
AND E.POS= ‘POS3’
consider
Select ….
Into ….
From
(A Inner join B on A.ID=B.ID) LEFT OUTER JOIN
STAR as C on
C.ID = A.ID AND
((C.Data = ’DEMO1’ AND C.POS= ’POS1’) OR
(C.Data = ’DEMO2’ AND C.POS= ’POS2’) or
(C.Data = ’DEMO3’ AND C.POS= ’POS3’))
Finally got my way through parenthesis.
Select ….
Into ….
From (((A
Inner join B on A.ID=B.ID)
LEFT OUTER JOIN STAR as C on (C.ID = A.ID
AND C.Data = ’DEMO1’
AND C.POS= ’POS1’))
LEFT OUTER JOIN STAR as D on (D.ID = A.ID
AND D.Data = ’DEMO2’
AND D.POS= ‘POS2’))
LEFT OUTER JOIN STAR as E on (E.ID = A.ID
AND E.Data = ’DEMO3’
AND E.POS= ‘POS3’)