SQL for Selecting Data with Codition - sql
in need a fast SQL for selcting my Data.
I have a Table a which look like the following:
And another Table b which look like the following:
In au can specify which data from b i need. Its the Flag a.kba_inkl (I = Inclusiv, E = Excluisiv)
The Key From both Tables are the first four Columns.
The First Row from a means all Artikel from b which has b.art_be = a.kba_be.
The Second Row from a means without Artickles from b where b.art_be = a.kba_be and b.art_wg = a.kba_wg. And so on.
In a: 0 means ALL (From 1-99)
In b can't appear a 0
Table a:
|------|------|------|-------|--------|
|kba_be|kba_wg|kba_ag|kba_anr|kba_inkl|
|------|------|------|-------|--------|
|10 |0 |0 |0 |I |
|------|------|------|-------|--------|
|10 |10 |0 |0 |E |
|------|------|------|-------|--------|
|10 |20 |30 |0 |E |
|------|------|------|-------|--------|
|20 |10 |0 |0 |I |
|------|------|------|-------|--------|
|20 |0 |0 |0 |E |
|------|------|------|-------|--------|
Table b:
|------|------|------|-------|
|art_be|art_wg|art_ag|art_anr|
|------|------|------|-------|
|10 |20 |30 |40 |
|------|------|------|-------|
|10 |10 |1 |5 |
|------|------|------|-------|
|10 |5 |30 |20 |
|------|------|------|-------|
|10 |10 |80 |50 |
|------|------|------|-------|
|10 |60 |30 |60 |
|------|------|------|-------|
|20 |10 |50 |50 |
|------|------|------|-------|
|20 |60 |30 |60 |
|------|------|------|-------|
Result:
|------|------|------|-------|
|art_be|art_wg|art_ag|art_anr|
|------|------|------|-------|
|10 |5 |30 |20 |
|------|------|------|-------|
|10 |60 |30 |60 |
|------|------|------|-------|
|20 |10 |50 |50 |
|------|------|------|-------|
Does anybody has an Idea?
Many thanks in advance.
EDIT: Maybe the Table a should be grouped like this:
|------|------|------|-------|--------|
|kba_be|kba_wg|kba_ag|kba_anr|kba_inkl|
|------|------|------|-------|--------|
|10 |0 |0 |0 |I |
|------|------|------|-------|--------|
|20 |0 |0 |0 |E |
|------|------|------|-------|--------|
|10 |10 |0 |0 |E |
|------|------|------|-------|--------|
|20 |10 |0 |0 |I |
|------|------|------|-------|--------|
|10 |20 |30 |0 |E |
|------|------|------|-------|--------|
And then loop through the rows.
So there are 2 parts of the query inclusive and exclusive.
The exclusive can be implemented using minus operator.
with a as
(
select 10 kba_be,0 kba_wg,0 kba_ag,0 kba_anr,'I' kba_incl from dual union all
select 10 kba_be,10 kba_wg,0 kba_ag,0 kba_anr,'E' kba_incl from dual union all
select 10 kba_be,20 kba_wg,30 kba_ag,0 kba_anr,'E' kba_incl from dual
),
b as
(
select 10 art_be,20 art_wg,30 art_ag,0 art_anr from dual union all
select 10 art_be,10 art_wg,1 art_ag,5 art_anr from dual union all
select 10 art_be,5 art_wg,30 art_ag,20 art_anr from dual union all
select 10 art_be,10 art_wg,80 art_ag,50 art_anr from dual union all
select 10 art_be,60 art_wg,30 art_ag,60 art_anr from dual
)
select b.* from
a,b
where
a.kba_incl = 'I'
and b.art_be = a.kba_be
and (b.art_wg = a.kba_wg or a.kba_wg=0)
and (b.art_ag = a.kba_ag or a.kba_ag=0)
minus
select b.* from
a,b
where
a.kba_incl = 'E'
and b.art_be = a.kba_be
and (b.art_wg = a.kba_wg or a.kba_wg=0)
and (b.art_ag = a.kba_ag or a.kba_ag=0)
result
10 5 30 20
10 60 30 60
Related
Postgres - How to achieve UNION behaviour with UNION ALL?
I have a table with parent and child ids. create table if not exists stack ( parent int, child int ) Each parent can have multiple children and each child can have multiple children again. insert into stack (parent, child) values (1,2), (2,3), (3,4), (4,5), (5,6), (6,7), (7,8), (8,9), (9,null), (1,7), (7,8), (8,9), (9,null); The data looks like this. |parent|child| |------|-----| |1 |2 | |2 |3 | |3 |4 | |4 |5 | |5 |6 | |6 |7 | |7 |8 | |8 |9 | |9 |NULL | |1 |7 | |7 |8 | |8 |9 | |9 |NULL | I'd like to find all children. I can use a recursive cte with a UNION ALL. with recursive cte as ( select child from stack where stack.parent = 1 union select stack.child from cte left join stack on cte.child = stack.parent where cte.child is not null ) select * from cte; This gives me the result I'd like to achieve. |child| |-----| |2 | |7 | |3 | |8 | |4 | |9 | |5 | |NULL | |6 | However I'd like to include the depth / level and also the path for each node. I can do this using a different recursive cte. with recursive cte as ( select parent, child, 0 as level, array[parent, child] as path from stack where stack.parent = 1 union all select stack.parent, stack.child, cte.level + 1, cte.path || stack.child from cte left join stack on cte.child = stack.parent where cte.child is not null ) select * from cte; That gives me this data. |parent|child|level|path | |------|-----|-----|--------------------| |1 |2 |0 |{1,2} | |1 |7 |0 |{1,7} | |2 |3 |1 |{1,2,3} | |7 |8 |1 |{1,7,8} | |7 |8 |1 |{1,7,8} | |3 |4 |2 |{1,2,3,4} | |8 |9 |2 |{1,7,8,9} | |8 |9 |2 |{1,7,8,9} | |8 |9 |2 |{1,7,8,9} | |8 |9 |2 |{1,7,8,9} | |4 |5 |3 |{1,2,3,4,5} | |9 | |3 |{1,7,8,9,} | |9 | |3 |{1,7,8,9,} | |9 | |3 |{1,7,8,9,} | |9 | |3 |{1,7,8,9,} | |9 | |3 |{1,7,8,9,} | |9 | |3 |{1,7,8,9,} | |9 | |3 |{1,7,8,9,} | |9 | |3 |{1,7,8,9,} | |5 |6 |4 |{1,2,3,4,5,6} | |6 |7 |5 |{1,2,3,4,5,6,7} | |7 |8 |6 |{1,2,3,4,5,6,7,8} | |7 |8 |6 |{1,2,3,4,5,6,7,8} | |8 |9 |7 |{1,2,3,4,5,6,7,8,9} | |8 |9 |7 |{1,2,3,4,5,6,7,8,9} | |8 |9 |7 |{1,2,3,4,5,6,7,8,9} | |8 |9 |7 |{1,2,3,4,5,6,7,8,9} | |9 | |8 |{1,2,3,4,5,6,7,8,9,}| |9 | |8 |{1,2,3,4,5,6,7,8,9,}| |9 | |8 |{1,2,3,4,5,6,7,8,9,}| |9 | |8 |{1,2,3,4,5,6,7,8,9,}| |9 | |8 |{1,2,3,4,5,6,7,8,9,}| |9 | |8 |{1,2,3,4,5,6,7,8,9,}| |9 | |8 |{1,2,3,4,5,6,7,8,9,}| |9 | |8 |{1,2,3,4,5,6,7,8,9,}| My problem is that I have a lot of duplicate data. I'd like to get the same result as the UNION query but with the level and the path. I tried something like where cte.child is not null and stack.parent not in (cte.parent) or where cte.child is not null and not exists (select parent from cte where cte.parent = stack.parent) but the first does not change anything and the second returns an error. ERROR: recursive reference to query "cte" must not appear within a subquery Any ideas? Thank you very much!
Your problem is inappropriate table data. Your table contains the information that 8 is a direct child to 7 twice for instance. I suggest you remove the duplicate data and implement a unique constraint on the pairs. If you cannot do so for some reason, make the rows distinct in your query: with recursive good_stack as (select distinct * from stack) ,cte as ( select parent, child, 0 as level, array[parent, child] as path from good_stack where good_stack.parent = 1 union all select good_stack.parent, good_stack.child, cte.level + 1, cte.path || good_stack.child from cte left join good_stack on cte.child = good_stack.parent where cte.child is not null and good_stack.child is not null ) select * from cte; Demo: https://dbfiddle.uk/?rdbms=postgres_13&fiddle=acb1d7a1a1d26c3fd9caf0e7dedc12b2 (You may also make the columns not nullable. The entries 9|null add no information. If the table were lacking these entries, 9 would still be without a child.)
Write SQL Server query
Help me please with query: select * from sc84 as nom join sc319 as p on p.PARENTEXT = nom.id join sc219 as pt on p.sp327 = pt.id join _1SCONST as c on c.objid=p.id As a result approximately such table Car / price_base / 08-08-2016:13-40 / 100 / Car / price_base / 08-08-2016:14-40 / 150 / Car / price_base / 08-09-2016:13-40 / 190 / Car / price_super / 08-09-2016:18-40 / 210 / Car / price_super / 08-10-2016:13-40 / 290 / I want to return Car / price_base / 08-09-2016:13-40 / 190 / Car / price_super / 08-10-2016:13-40 / 290 / That is good, types of the price of date and their value. Prompt please how to get the last (the current price for each type of the price and each goods) tried options with group but there is obviously not enough skill. nom.id - PK SKU pt.id - PK price type p.id -PK price p.parentext - parent price (sku) p.sp327 - FK to price type date = date column I am using SQL Server 2008. Table structure T=1SCONST | ----Columns------- Name |Descr |Type|Length|Precision F=ROW_ID |Row ID |I |0 |0 F=OBJID |ID obj(0-cons ) |C |9 |0 F=ID |ID parameter |I |0 |0 F=DATE |Fix date |D |0 |0 F=VALUE |valume |V |255 |0 F=DOCID |ID Document |C |9 |0 F=TIME |Time |I |0 |0 F=ACTNO |Action No |I |0 |0 F=LINENO_ |LineNo |S |0 |0 F=TVALUE | |C |3 |0 T=SC319 | ----Columns------- Name |Descr |Type|Length|Precision F=ROW_ID |Row ID |I |0 |0 F=ID |ID object |C |9 |0 F=PARENTEXT |Parent in other tabl|C |9 |0 F=ISMARK |Object is Marked for|L |0 |0 F=VERSTAMP |Version stamp |I |0 |0 F=SP6681 |(P)Âàëþòà |C |9 |0 F=SP6682 |(P)Ïðîöåíò |N |5 |2 F=SP327 |(P)ÒèïÖåí |C |9 |0 T=SC319 |Ñïðàâî÷íèê Öåíû |SC319 |R # ----Columns------- # Name |Descr |Type|Length|Precision F=ROW_ID |Row ID |I |0 |0 F=ID |ID object |C |9 |0 F=PARENTEXT |Parent in other tabl|C |9 |0 F=ISMARK |Object is Marked for|L |0 |0 F=VERSTAMP |Version stamp |I |0 |0 F=SP6681 |(P)Âàëþòà |C |9 |0 F=SP6682 |(P)Ïðîöåíò |N |5 |2 F=SP327 |(P)ÒèïÖåí |C |9 |0 #==TABLE no 24 : Ñïðàâî÷íèê Íîìåíêëàòóðà # Name |Descr |SQLTableNam|RecordLock T=SC84 |Ñïðàâî÷íèê Íîìåíêëàòóðà |SC84 |R # ----Columns------- # Name |Descr |Type|Length|Precision F=ROW_ID |Row ID |I |0 |0 F=ID |ID object |C |9 |0 F=PARENTID |ID parent obj |C |9 |0 F=CODE |object code |C |8 |0 F=DESCR |object description |C |70 |0 F=ISFOLDER |Is Line - Folder |Y |0 |0 F=ISMARK |Object is Marked for|L |0 |0 F=VERSTAMP |Version stamp |I |0 |0 F=SP85 |(P)Àðòèêóë |C |25 |0 F=SP86 |(P)ÁàçîâàÿÅäèíèöà |C |9 |0 F=SP208 |(P)Âåñîâîé |N |1 |0 F=SP2417 |(P)ÂèäÍîìåíêëàòóðû |C |9 |0 F=SP97 |(P)ÌèíÎñòàòîê |N |13 |3 F=SP5066 |(P)ÍåÂêëþ÷àòüÂïðàéñ |N |1 |0 F=SP5013 |(P)ÍîìåðÃÒÄ |C |9 |0 F=SP94 |(P)ÎñíîâíàÿÅäèíèöà |C |9 |0 F=SP4427 |(P)ÎñíîâíîåÑâîéñòâî |C |9 |0 F=SP103 |(P)ÑòàâêàÍÄÑ |C |9 |0 F=SP104 |(P)ÑòàâêàÍÏ |C |9 |0 F=SP5012 |(P)ÑòðàíàÏðîèñõîæäåí|C |9 |0 F=SP8574 |(P)ÍèçÎòêëîíåíèÿÑåáå|N |4 |2 F=SP8575 |(P)ÂåðõÎòêëîíåíèÿÑåá|N |4 |2 F=SP8576 |(P)ÍèçÎòêëîíåíèÿÑïåö|N |4 |2 F=SP8577 |(P)ÂåðõÎòêëîíåíèÿÑïå|N |4 |2 F=SP8578 |(P)ÍèçÎòêëîíåíèÿÇàêó|N |4 |2 F=SP8579 |(P)ÂåðõÎòêëîíåíèÿÇàê|N |4 |2 F=SP8580 |(P)ÍèçÎòêëîíåíèÿÐîçí|N |4 |2 F=SP8581 |(P)ÂåðõÎòêëîíåíèÿÐîç|N |4 |2 F=SP8599 |(P)Äëèíà |N |6 |2 F=SP8600 |(P)Øèðèíà |N |6 |2 F=SP8601 |(P)Âûñîòà |N |6 |2 F=SP8602 |(P)Îáúåì |N |14 |5 F=SP8606 |(P)ÌàêñèìàëüíûéÏðîöå|N |4 |2 F=SP8607 |(P)Àäðåñ |C |9 |0 F=SP95 |(P)Êîììåíòàðèé |M |0 |0 F=SP101 |(P)ÏîëíÍàèìåíîâàíèå |M |0 |0
select * from ( select *, ROW_NUMBER() over(partition by nom.id,pt.id order by c.date desc) NUM from sc84 as nom join sc319 as p on p.PARENTEXT = nom.id join sc219 as pt on p.sp327 = pt.id join _1SCONST as c on c.objid=p.id ) A where NUM=1
Oracle: Recursively self referential join with nth level record
I have self referential table like this: id |level | parent_id ---------------------- 1 |1 |null 2 |1 |null 3 |2 |1 4 |2 |1 5 |2 |2 6 |3 |5 7 |3 |3 8 |4 |7 9 |4 |6 ------------------------ I need nth level parent in result. for example 2nd level parent id |level | parent_id| second_level_parent_id ------------------------------------------------ 1 |1 |null |null 2 |1 |null |null 3 |2 |1 |null 4 |2 |1 |null 5 |2 |2 |null 6 |3 |5 |5 7 |3 |3 |3 8 |4 |7 |3 9 |4 |6 |5 -------------------------------------------------
this works for me. SELECT m.*, CONNECT_BY_ROOT id AS second_level_parent_id FROM my_table m WHERE CONNECT_BY_ROOT level =2 CONNECT BY prior id = parent_id; thanks #Jozef Dúc
SQL: Need to SUM column for each type
How can I find the SUM of all scores for the minimum date of each lesson_id please: ----------------------------------------------------------- |id |uid |group_id |lesson_id |game_id |score |date | ----------------------------------------------------------- |1 |145 |1 |1 |0 |40 |1391627323 | |2 |145 |1 |1 |0 |80 |1391627567 | |3 |145 |1 |2 |0 |40 |1391627323 | |4 |145 |1 |3 |0 |30 |1391627323 | |5 |145 |1 |3 |0 |90 |1391627567 | |6 |145 |1 |4 |0 |20 |1391628000 | |7 |145 |1 |5 |0 |35 |1391628000 | ----------------------------------------------------------- I need output: ------------------- |sum_first_scores | ------------------- |165 | ------------------- I have this so far, which lists the score for each minimum date, per lesson, but I need to sum those results as above: SELECT lesson_id, MIN(date), score AS first_score FROM cdu_user_progress WHERE cdu_user_progress.uid = 145 GROUP BY lesson_id
You can identify the first score as the one where no earlier record exists. Then just take the sum: select sum(score) from edu_user_progress eup where cdu_user_progress.uid = 145 and not exists (select 1 from edu_user_progress eup2 where eup2.uid = eup.uid and eup2.lesson_id = eup.lesson_id and eup2.date < eup.date ); This assumes that the minimum date for the lesson id has only one score.
SQL - get rows where column is greater than certain amount
I need to get the sum of the scores for the first of each lesson_id, but I also need the overall min and max scores for all lesson_ids as well as some other info: cdu_groups: ---------------- |id |name | ---------------- |1 |group_1 | |2 |group_2 | ---------------- cdu_user_progress145: ----------------------------------------------------------- |id |uid |group_id |lesson_id |game_id |score |date | ----------------------------------------------------------- |1 |145 |1 |1 |0 |40 |1391627323 | |2 |145 |1 |1 |0 |80 |1391627567 | |3 |145 |1 |2 |0 |40 |1391627323 | |4 |145 |1 |3 |0 |30 |1391627323 | |5 |145 |1 |3 |0 |90 |1391627567 | |6 |145 |1 |4 |0 |20 |1391627323 | |7 |145 |1 |5 |0 |35 |1391627323 | ----------------------------------------------------------- I need this output: ----------------------------------------------------------------- |name |group_id |min_score |max_score |... |sum_first_scores | ----------------------------------------------------------------- |group_1 |1 |20 |90 |... |165 | ----------------------------------------------------------------- SELECT cdu_groups.*, MAX(score) AS max_score, MIN(score) AS min_score, COUNT(DISTINCT(lesson_id)) AS scored_lesson_count, COUNT(DISTINCT CASE WHEN score >= 75 then lesson_Id ELSE NULL END) as passed_lesson_count, SUM(first_scores.first_score) AS sum_first_scores FROM cdu_user_progress JOIN cdu_groups ON cdu_groups.id = cdu_user_progress.group_id JOIN ( SELECT lesson_id, MIN(date), score AS first_score FROM cdu_user_progress WHERE cdu_user_progress.uid = 145 GROUP BY lesson_id ) AS first_scores ON first_scores.lesson_id = cdu_user_progress.lesson_id WHERE cdu_user_progress.uid = 145 I'm getting this error though: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SUM(first_scores.first_score) AS sum_first_scores FROM cdu_user_progress ' at line 7