I'm trying to return a single row based on this where statement
WHERE
(C.id = G.community_id
AND P.service_type_id = G.service_type_id
AND I.unit_class_id = G.unit_class_id)
OR
(C.id = G.community_id
AND P.service_type_id = G.service_type_id)
The issue is I have to get a row based on multiple criteria and the more that match determines the final match. The statement above returns a row just fine if it matches the bottom or statement, but if it matches the first OR it returns results for both statements.
LIMIT 1 doesn't work either as sometimes it gives preference to the wrong result.
EDIT:
community_id
service_type_id
unit_class_id
1
1
1
1
1
null
Because of the way the table is both rows are true, my understanding was SQL took the first one that was true and returned it.
I apologize for not a lot of info I was hoping maybe there was just a bit of info I was missing. Here is my query.
CREATE VIEW view_invoice_line_item_gl_code
AS
SELECT
DISTINCT(ILI.invoice_line_item_id) AS invoice_line_item_id,
C.community_id AS community_id,
S.service_type_id AS service_type_id,
U.unit_class_id AS unit_class_id,
LIP.line_item_provider_id AS line_item_provider_id,
(SELECT gl_code_id
FROM gl_code G
WHERE (C.community_id = G.community_id
AND P.service_type_id = G.service_type_id)
AND ((G.unit_class_id IS NULL
AND G.line_item_provider_id IS NULL)
OR
(I.unit_class_id = G.unit_class_id
AND G.line_item_provider_id IS NULL)
OR
(I.unit_class_id = G.unit_class_id
AND ILI.line_item_provider_id = G.line_item_provider_id)
)) AS gl_code_id
FROM
invoice I
JOIN
invoice_line_item ILI ON (ILI.invoice_id = I.invoice_id)
JOIN
invoice_header IH ON (I.invoice_header_id = IH.invoice_header_id)
JOIN
provider_community_account PC ON (I.provider_community_account_id = PC.provider_community_account_id)
JOIN
line_item_provider LIP ON (ILI.line_item_provider_id = LIP.line_item_provider_id)
JOIN
unit_class U ON (I.unit_class_id = U.unit_class_id)
JOIN
community C ON (PC.community_id = C.community_id)
JOIN
provider P ON (PC.provider_id = P.provider_id)
JOIN
service_type S ON (P.service_type_id = S.service_type_id)
I'm assuming that you want to get the record that matches the most conditions first. One way to do that is to order by the number of matching conditions (in this case only one condition is different):
SELECT TOP 1 ...
FROM ...
WHERE
C.id = G.community_id
AND P.service_type_id = G.service_type_id
ORDER BY CASE WHEN I.unit_class_id = G.unit_class_id THEN 1 ELSE 0 END DESC
The first condition implies the second, so you can simplify it like this:
WHERE
C.id = G.community_id
AND P.service_type_id = G.service_type_id
You say where (A AND B) OR A so where A is sufficient.
You'll need to compute a "score" somehow. If you consider each predicate awards 1 point, then you could do something like:
select *
from (
select *,
case when <predicate1> then 1 else 0 end +
case when <predicate2> then 1 else 0 end as score
from t
WHERE
(C.id = G.community_id
AND P.service_type_id = G.service_type_id
AND I.unit_class_id = G.unit_class_id
)
OR
(
C.id = G.community_id
AND P.service_type_id = G.service_type_id
)
)
ORDER BY score DESC
LIMIT 1
We have an error in production, luckily have a manual solution for this, however I have to run below two queries every morning to fix the error. This is so manual, I want to automate this and combine two queries into one. However we only have this error in production and not in DEV or QA, if I mess up with the combining query that will end up a chaos, So I need your expertise.
1st Query brings project numbers
select id, ugenProjectNumber
from unifier_uxpecai
where (pecaiChecklistNumber = 0 or pecaiChecklistNumber is null)
or (pecaiChecklistItemNumber = 0 or pecaiChecklistItemNumber is null)
2nd Query fix broken links between action items and list items, I manually put 1st query results unique project numbers into second query and run the second query per each unique project numbers.
update unifier_uxpecai pai
set (pai.pecaiChecklistNumber, pai.pecaiChecklistItemNumber) =
(
select pcl.id, pcli.id
from unifier_uxpecl pcl
inner join unifier_uxpecl_lineitem pcli on pcli.uuu_tab_id = 0 and
pcli.record_id = pcl.id
where pcl.ugenProjectNumber = 'GL-16-161010-143502'
and pcli.pecItemActionItemBPC = pai.id
)
where exists
(
select pcli.pecItemActionItemBPC
from unifier_uxpecl pcl
inner join unifier_uxpecl_lineitem pcli on pcli.uuu_tab_id = 0 and
pcli.record_id = pcl.id
where pcl.ugenProjectNumber = 'GL-16-161010-143502'
and pcli.pecItemActionItemBPC = pai.id
)
and (pai.pecaiChecklistNumber = 0 or pai.pecaiChecklistItemNumber = 0)
You can incorporate the logic into the queries:
update unifier_uxpecai pai
set (pai.pecaiChecklistNumber, pai.pecaiChecklistItemNumber) =
(select pcl.id, pcli.id
from unifier_uxpecl pcl join
unifier_uxpecl_lineitem pcli
on pcli.uuu_tab_id = 0 and pcli.record_id = pcl.id
where pcl.ugenProjectNumber in (select ugenProjectNumber
from unifier_uxpecai
where (pecaiChecklistNumber = 0 or pecaiChecklistNumber is null) or
(pecaiChecklistItemNumber = 0 or pecaiChecklistItemNumber is null
) and
pcli.pecItemActionItemBPC = pai.id
)
where exists
(
select pcli.pecItemActionItemBPC
from unifier_uxpecl pcl join
unifier_uxpecl_lineitem pcli
on pcli.uuu_tab_id = 0 and
pcli.record_id = pcl.id
where pcl.ugenProjectNumber in (select ugenProjectNumber
from unifier_uxpecai
where (pecaiChecklistNumber = 0 or pecaiChecklistNumber is null) or
(pecaiChecklistItemNumber = 0 or pecaiChecklistItemNumber is null
) and
pcli.pecItemActionItemBPC = pai.id
) and
(pai.pecaiChecklistNumber = 0 or pai.pecaiChecklistItemNumber = 0)
I am new to SQLDeveloper. Please help me in correcting the merge syntax.I want to merge the data from act_sl tavle into act_sls_0 table
I am using 2 joins in From Clause.
But I am Getting Errors :
Error(13,13): PL/SQL: ORA-00969: missing ON keyword
Error(4,1): PL/SQL: SQL Statement ignored
merge into act_sls_0 using(
( select * from
(select a_0.asp, gadim.uic as ga, pmm_styleid, week, colorcode , sizecode, storenum, units_asly,retail_asly,
cost_asly ,units_asregly,retail_asregly,units_asmkdly,retail_asmkdly,units_as_pln,retail_as_pln
from act_sls
join dimension w on w.externalkey = 'W'||substr(WEEK,3,2)||'_'||substr(WEEK,5,2)
join a_0 on ( w.externalkey between startweek and endweek)
join dimension strdim on strdim.externalkey = (case when length(storenum) <= 4 then RPAD('STR-', 8 - length(storenum), '0') else 'STR-' END) || storenum
join store_info_0 str on store = strdim.uic
join dimension gadim on gadim.externalkey = decode(store_type, 'RETAIL', 'GA-01', 'ECOM', 'GA-02', '')
where trendweeks < 6)t1
join(select distinct asp, product, ga, color, sstyl_shade, pmm_styleid from aplc_1 aplc
join apc_1 apc using (asp,product,color)
where activeitem = 1 and ga!=0 and color != 0)t2
on (t1.asp = t2.asp and
t1.pmm_styleid = t2.pmm_styleid
and (case when length(t1.colorcode) <= 4 then RPAD('SHD-', 8 - length(t1.colorcode), '0') else 'SHD-' END) || t1.colorcode = t2.sstyl_shade
and t1.ga = t2.ga))src
on (trg.asp = src.asp and trg.pmm_styleid = src.pmm_styleid and trg.colorcode = src.colorcode and trg.ga = src.ga)
when matched THEN
update SET
when matched THEN
update SET
trg.UNITS_ASLY = src.UNITS_ASLY,
trg.RETAIL_ASLY = src.RETAIL_ASLY,
trg.COST_ASLY = src.COST_ASLY,
trg.UNITS_ASREGLY = src.UNITS_ASREGLY,
trg.RETAIL_ASREGLY = src.RETAIL_ASREGLY,
trg.UNITS_ASMKDLY = src.UNITS_ASMKDLY,
trg.RETAIL_ASMKDLY = src.RETAIL_ASMKDLY,
trg.UNITS_AS_PLN = src.UNITS_AS_PLN,
trg.RETAIL_AS_PLN = src.RETAIL_AS_PLN
when not matched then insert
(trg.asp,trg.ga, trg.pmm_styleid, trg.colorcode,trg.sizecode,trg.storenum,trg.week,trg.UNITS_ASLY,trg.RETAIL_ASLY ,trg.COST_ASLY , trg.UNITS_ASREGLY ,trg.RETAIL_ASREGLY ,
trg.UNITS_ASMKDLY ,trg.RETAIL_ASMKDLY ,trg.UNITS_AS_PLN ,trg.RETAIL_AS_PLN )
values
(src.asp,src.ga, src.pmm_styleid, src.colorcode,src.sizecode,src.storenum,src.week,src.UNITS_ASLY,src.RETAIL_ASLY,src.COST_ASLY,src.UNITS_ASREGLY,
src.RETAIL_ASREGLY, src.UNITS_ASMKDLY, src.RETAIL_ASMKDLY, src.UNITS_AS_PLN, src.RETAIL_AS_PLN);
The format for a merge statement is:
merge into <target_table> tgt
using <table_name or subquery> src
on (<join conditions between the target and source datasets>)
when matched then
update set ...
when not matched then
insert (...)
values (...);
Quite apart from the fact that your source subquery is incorrect (there are errors around where the t1 and t2 are; too many brackets, inappropriately trying to alias something etc), whilst you have join conditions inside your subquery, you're completely missing the ON clause for the merge itself.
You need to define the join conditions that match the data returned by your source subquery to your target table.
Now the error is : src.ga - Invalid Identifier
Although I have ga table in Trg table and src table .
merge into act_sls_0 trg using( select * from
(select a_0.asp, gadim.uic as ga, pmm_styleid, week, colorcode , sizecode, storenum, units_asly,retail_asly,
cost_asly ,units_asregly,retail_asregly,units_asmkdly,retail_asmkdly,units_as_pln,retail_as_pln
from act_sls
join dimension w on w.externalkey = 'W'||substr(WEEK,3,2)||'_'||substr(WEEK,5,2)
join a_0 on ( w.externalkey between startweek and endweek)
join dimension strdim on strdim.externalkey = (case when length(storenum) <= 4 then RPAD('STR-', 8 - length(storenum), '0') else 'STR-' END) || storenum
join store_info_0 str on store = strdim.uic
join dimension gadim on gadim.externalkey = decode(store_type, 'RETAIL', 'GA-01', 'ECOM', 'GA-02', '')
where trendweeks < 6)t1
join(select distinct asp, product, ga, color, sstyl_shade, pmm_styleid from aplc_1 aplc
join apc_1 apc using (asp,product,color)
where activeitem = 1 and ga!=0 and color != 0)t2
on (t1.asp = t2.asp and
t1.pmm_styleid = t2.pmm_styleid
and (case when length(t1.colorcode) <= 4 then RPAD('SHD-', 8 - length(t1.colorcode), '0') else 'SHD-' END) || t1.colorcode = t2.sstyl_shade
and t1.ga = t2.ga))src
on (trg.asp = src.asp and trg.pmm_styleid = src.pmm_styleid and trg.colorcode = src.colorcode and trg.ga = src.ga)
when matched THEN
update SET
trg.UNITS_ASLY = src.UNITS_ASLY,
trg.RETAIL_ASLY = src.RETAIL_ASLY,
trg.COST_ASLY = src.COST_ASLY,
trg.UNITS_ASREGLY = src.UNITS_ASREGLY,
trg.RETAIL_ASREGLY = src.RETAIL_ASREGLY,
trg.UNITS_ASMKDLY = src.UNITS_ASMKDLY,
trg.RETAIL_ASMKDLY = src.RETAIL_ASMKDLY,
trg.UNITS_AS_PLN = src.UNITS_AS_PLN,
trg.RETAIL_AS_PLN = src.RETAIL_AS_PLN
when not matched then insert
(trg.asp,trg.ga, trg.pmm_styleid, trg.colorcode,trg.sizecode,trg.storenum,trg.week,trg.UNITS_ASLY,trg.RETAIL_ASLY ,trg.COST_ASLY ,trg.UNITS_ASREGLY ,trg.RETAIL_ASREGLY ,
trg.UNITS_ASMKDLY ,trg.RETAIL_ASMKDLY ,trg.UNITS_AS_PLN ,trg.RETAIL_AS_PLN )
values
(src.asp,src.ga, src.pmm_styleid, src.colorcode,src.sizecode,src.storenum,src.week,src.UNITS_ASLY,src.RETAIL_ASLY,src.COST_ASLY,src.UNITS_ASREGLY,
src.RETAIL_ASREGLY, src.UNITS_ASMKDLY, src.RETAIL_ASMKDLY, src.UNITS_AS_PLN, src.RETAIL_AS_PLN);
commit;
I'm loading a fact table using MERGE and it's taking 44 minutes for 1 million records. Is there a way I can improve this?
My query:
MERGE INTO dbo.FactProjMarketCode AS target
USING (
SELECT
SourceSystem = 'ORACLE_ERP',
ProjMarketCodeSourceId = jmc.XT_JOB_MARKETING_CODE_ID,
p.ProjectId,
MarketCodeId = ISNULL(mc.MarketingCodeId,-1),
Weight = 0.01 * ISNULL(jmc.WEIGHT,100),
WasMissing = CASE WHEN jmc.WEIGHT IS NULL THEN 1 ELSE 0 END,
jmc.LAST_UPDATE_DATE
FROM
dimProject p
LEFT JOIN stage.XT_JOB_MARKETING_CODE jmc
ON p.ProjectSourceId = jmc.XT_PROJECT_ID
LEFT JOIN DimMarketingCode mc
ON jmc.MARKETING_CODE = mc.MarketingCode -- should create column MarketingCodeSourceId
AND mc.SourceSystem = 'ORACLE_ERP'
WHERE
p.SourceSystem = 'ORACLE_ERP'
) AS source
ON target.SourceSystem = source.SourceSystem
AND target.ProjMarketCodeSourceId = source.ProjMarketCodeSourceId
WHEN MATCHED AND source.LAST_UPDATE_DATE > target.LAST_UPDATE_DATE
THEN UPDATE SET
target.ProjectId = source.ProjectId,
target.MarketCodeId = source.MarketCodeId,
target.Weight = source.WEIGHT,
target.WasMissing = source.WasMissing,
target.LAST_UPDATE_DATE = source.LAST_UPDATE_DATE
WHEN NOT MATCHED BY target
THEN INSERT (
SourceSystem,
ProjMarketCodeSourceId,
ProjectId,
MarketCodeId,
Weight,
WasMissing,
LAST_UPDATE_DATE
) VALUES (
source.SourceSystem,
source.ProjMarketCodeSourceId,
source.ProjectId,
source.MarketCodeId,
source.Weight,
source.WasMissing,
source.LAST_UPDATE_DATE
)
WHEN NOT MATCHED BY source
THEN DELETE;
I am trying to extract the data from SQL developer which matches two row conditions. Both the rows has one unique value ( ID ) and table name is abc.tcd
ID = Type = GL code = amount
1 = Debit = 0701 = 10000
1 = credit = 0601 = 10000
1 = Credit= 0501 = 1000
1 = Debit= 0401 = 1000
2 = Debit = 0701 = 9000
2 = credit = 0801 = 9000
3 = Debit = 0701 = 6000
3 = credit = 0601 = 6000
Condition 1 :
GL code = '0701' having Type = 'Debit'
condition 2 :
GL code = '0601' having Type = 'Credit'
Expected output :
ID Type GL code amount
1 = Debit = 0701 = 10000
1 = credit = 0601 = 10000
1 = Credit = 0501 = 1000
1 = Debit = 0401 = 1000
3 = Debit = 0701 = 6000
3 = credit = 0601 = 6000
Output should display all the rows based on ID
If I understand the question correctly, you want to extract all the rows for some ID where two different rows fulfill two different conditions. you could use a couple of in operators:
SELECT *
FROM mytable
WHERE id IN (SELECT id
FROM my_table
WHERE GLCode = '0701' AND Type = 'Debit')
AND id IN (SELECT id
FROM my_table
WHERE GLCode = '0601' AND Type = 'Credit')
Of course, this can be easily translated to use the exists operator:
SELECT *
FROM mytable a
WHERE EXISTS (SELECT *
FROM my_table b
WHERE a.id = b.id AND b.GLCode = '0701' AND b.Type = 'Debit')
AND EXISTS (SELECT *
FROM my_table c
WHERE a.id = c.id AND c.GLCode = '0601' AND c.Type = 'Credit')
A more elegant way might be to have all the conditions in a single query with ors and count how many of them are fulfilled:
SELECT *
FROM mytable
WHERE id IN (SELECT id
FROM my_table
WHERE (GLCode = '0701' AND Type = 'Debit') OR
(GLCode = '0601' AND Type = 'Credit')
GROUP BY id
HAVING COUNT(*) = 2)
Another alternative:
SELECT * FROM MyTable
INNER JOIN
(
SELECT ID
FROM MyTable
WHERE (GLCode = '0701' AND Type = 'Debit') OR (GLCode = '0601' AND Type = 'Credit')
GROUP BY ID
HAVING COUNT(DISTINCT GLCode) = 2 AND COUNT(DISTINCT Type) = 2
) X
ON MyTable.ID = x.ID;
SqlFiddle here
Basically "find the ids having two distinct rows meeting the criteria". We then return all rows with this ID
Edit
Your real query would look like:
SELECT *
FROM tbaadm.ctd
INNER JOIN
(SELECT Tran_id
FROM tbaadm.ctd
WHERE ((GL_SUB_HEAD_CODE = '06106' AND PART_TRAN_TYPE = 'C')
OR (GL_SUB_HEAD_CODE = '29101' AND PART_TRAN_TYPE = 'D'))
AND (tran_date >= '01-12-2014' AND tran_date < '30-12-2014')
GROUP BY Tran_id
HAVING COUNT(DISTINCT GL_SUB_HEAD_CODE) = 2 AND COUNT(DISTINCT PART_TRAN_TYPE) = 2
) X
ON tbaadm.ctd = x.Tran_id;
The parenthesis around the ANDs are obviously redundant due to operator precedence, but might help with readability?
Also, note with Date range checking that it is convention to include start date but exclude end date, viz x >= start and x < end