patternMinor
I need the identical lines to merge
Viewed 0 times
themergeneedidenticallines
Problem
Previous question: Return row with values if nothing fits the conditions
I almost got this working.
The problem that I have is that this variant of query does not merge the line from the SELECT with the one in the UNION if they are the same:
This is what SVINVD looks like:
This is what GESUPD looks like:
No line for "PRODUIT5" here.
So in consequence I get a doubled line:
I almost got this working.
The problem that I have is that this variant of query does not merge the line from the SELECT with the one in the UNION if they are the same:
SELECT CODPRO, VALPRO, COALESCE(SUM(UVCLIV), 0) AS SUM
FROM FGE50LM0TV.GESUPD
WHERE CNFLIG = '2'
AND CODPRO IN (SELECT VALINV FROM FGE50LM0TV.SVINVD WHERE NUMINV = 59)
GROUP BY CODACT, CODPRO, VALPRO
UNION (SELECT VALINV, 0, 0 FROM FGE50LM0TV.SVINVD WHERE NUMINV = 59) ;This is what SVINVD looks like:
This is what GESUPD looks like:
No line for "PRODUIT5" here.
So in consequence I get a doubled line:
Solution
The
CODPRO
VALPRO
SUM
PRODUCT3
0
212
will not merge with row
CODPRO
VALPRO
SUM
PRODUCT3
0
0
because the values in the last column differ.
Anyway, if the goal is to complete the set returned by
with missing values found in
then there are a few approaches to this.
There are repetitive bits of logic here, like the
Use your query as a derived table and outer-join it to
You can also try outer-joining
Note that the
While generally looking simpler than the other
UNION operator eliminates duplicate rows. It means that two rows will merge only if they are completely identical. RowCODPRO
VALPRO
SUM
PRODUCT3
0
212
will not merge with row
CODPRO
VALPRO
SUM
PRODUCT3
0
0
because the values in the last column differ.
Anyway, if the goal is to complete the set returned by
SELECT CODPRO, VALPRO, COALESCE(SUM(UVCLIV), 0) AS SUM
FROM FGE50LM0TV.GESUPD
WHERE CNFLIG = '2'
AND CODPRO IN (SELECT VALINV FROM FGE50LM0TV.SVINVD WHERE NUMINV = 59)with missing values found in
SELECT VALINV FROM FGE50LM0TV.SVINVD WHERE NUMINV = 59then there are a few approaches to this.
UNION+EXCEPT
SELECT CODPRO, VALPRO, COALESCE(SUM(UVCLIV), 0) AS SUM
FROM FGE50LM0TV.GESUPD
WHERE CNFLIG = '2'
AND CODPRO IN (SELECT VALINV FROM FGE50LM0TV.SVINVD WHERE NUMINV = 59)
UNION
(
SELECT VALINV, 0, 0 FROM FGE50LM0TV.SVINVD WHERE NUMINV = 59
EXCEPT
SELECT CODPRO, 0, 0 FROM FGE50LM0TV.GESUPD WHERE CNFLIG = '2'
)There are repetitive bits of logic here, like the
CNFLIG = '2' – an aspect which I personally prefer to avoid in my queries if possible. Other than that, this seems like more or less straightforward approach to me.LEFT JOIN
Use your query as a derived table and outer-join it to
FGE50LM0TV.SVINVD. Substitute 0 for missing rows' VALPRO and SUM. Like this:SELECT
s.VALINV AS CODPRO, COALESCE(g.VALPRO, 0) AS VALPRO, COALESCE(g.SUM, 0) AS SUM
FROM
FGE50LM0TV.SVINVD AS s
LEFT JOIN
(
SELECT
CODPRO, VALPRO, COALESCE(SUM(UVCLIV), 0) AS SUM
FROM
FGE50LM0TV.GESUPD
WHERE
CNFLIG = '2'
) AS g ON s.VALINV = g.CODPRO
WHERE
s.NUMINV = 59
;LEFT JOIN, Alternative Option
You can also try outer-joining
FGE50LM0TV.GESUPD to FGE50LM0TV.SVINVD directly, and then apply the grouping:SELECT
s.VALINV AS CODPRO, COALESCE(g.VALPRO, 0) AS VALPRO, COALESCE(SUM(g.UVCLIV), 0) AS SUM
FROM
FGE50LM0TV.SVINVD AS s
LEFT JOIN FGE50LM0TV.GESUPD AS g ON s.VALINV = g.CODPRO AND g.CNFLIG = '2'
WHERE
s.NUMINV = 59
GROUP BY
s.VALINV, g.VALPRO
;Note that the
CNFLIG = '2' is moved from WHERE to the ON clause. This is so as to avoid eliminating non-matching GESUPD entries. The WHERE clause applies to the entire joined set, and where GESUPD has no match for SVINVD, the CNFLIG = '2' would completely exclude that row from the output, contrary to what you are trying to achieve. In the ON clause, however, the condition would apply to GESUPD only, and SVINVD rows that have no match would still be returned.While generally looking simpler than the other
LEFT JOIN solution, this option may not necessarily be as fast. You will have to test both to compare the performance for yourself. Naturally, that goes for all three options.Code Snippets
SELECT CODPRO, VALPRO, COALESCE(SUM(UVCLIV), 0) AS SUM
FROM FGE50LM0TV.GESUPD
WHERE CNFLIG = '2'
AND CODPRO IN (SELECT VALINV FROM FGE50LM0TV.SVINVD WHERE NUMINV = 59)SELECT VALINV FROM FGE50LM0TV.SVINVD WHERE NUMINV = 59SELECT CODPRO, VALPRO, COALESCE(SUM(UVCLIV), 0) AS SUM
FROM FGE50LM0TV.GESUPD
WHERE CNFLIG = '2'
AND CODPRO IN (SELECT VALINV FROM FGE50LM0TV.SVINVD WHERE NUMINV = 59)
UNION
(
SELECT VALINV, 0, 0 FROM FGE50LM0TV.SVINVD WHERE NUMINV = 59
EXCEPT
SELECT CODPRO, 0, 0 FROM FGE50LM0TV.GESUPD WHERE CNFLIG = '2'
)SELECT
s.VALINV AS CODPRO, COALESCE(g.VALPRO, 0) AS VALPRO, COALESCE(g.SUM, 0) AS SUM
FROM
FGE50LM0TV.SVINVD AS s
LEFT JOIN
(
SELECT
CODPRO, VALPRO, COALESCE(SUM(UVCLIV), 0) AS SUM
FROM
FGE50LM0TV.GESUPD
WHERE
CNFLIG = '2'
) AS g ON s.VALINV = g.CODPRO
WHERE
s.NUMINV = 59
;SELECT
s.VALINV AS CODPRO, COALESCE(g.VALPRO, 0) AS VALPRO, COALESCE(SUM(g.UVCLIV), 0) AS SUM
FROM
FGE50LM0TV.SVINVD AS s
LEFT JOIN FGE50LM0TV.GESUPD AS g ON s.VALINV = g.CODPRO AND g.CNFLIG = '2'
WHERE
s.NUMINV = 59
GROUP BY
s.VALINV, g.VALPRO
;Context
StackExchange Database Administrators Q#296277, answer score: 4
Revisions (0)
No revisions yet.