MySQL SUM Query - sql

I've got two tables.
I'm trying to calculating the SUM quantity of tbl1
tbl1.xid is the primary, while tbl2.xid is the foreign
tbl1
xid pub quantity
1 1 10
2 1 2
3 0 1
4 1 5
tbl2
id ttype fno xid qnty
1 A 0 1 0
2 A 1 1 3
3 B 1 1 4
4 A 1 2 1
5 A 1 3 2
6 A 1 4 3
7 A 1 4 1
8 A 0 1 0
We are calculating the sum of tbl1's quantity
1) Whos tbl1.pub is 1
Thus tbl1.xid 3 is removed form the list, for it's pub is 0
Results
tbl1
xid pub quantity
1 1 10
2 1 2
4 1 5
2) AND Who's tbl1 has at least one tbl2.xid who's tbl2.ttype is 'A' and who's tbl2.fno is '0'
Thus tbl1.xid 2 & 4 are removed form the list, because none of them have at least one tbl2.xid who's fno is '0' and who's tbl2.ttype is 'A'
Results
parent_tbl1
xid pub quantity
1 1 10
The final results should be 10

SELECT SUM(quantity) AS Total
FROM tbl1
WHERE pub=1
AND EXISTS
(SELECT *
FROM tbl2
WHERE tbl2.ttype = 'A'
AND tbl2.fno = 0
AND tbl1.xid = tbl2.xid
)

Related

How to get the data with a condition for other table?

My query:
SELECT skill_code FROM TableSkills
I have tables TableSkills and TableUsers. How can I achieve skill_code data that only shows the skill_code if the user from TableUsers has at least "1"?
Expected result :
skill_code
Skill_1
Skill_2
Skill_3
Skill_6
TableSkills :
ID
skill_code
1
Skill 1
2
Skill 2
3
Skill 3
4
Skill 4
5
Skill 5
6
Skill 6
TableUsers :
ID
User
Skill_1
Skill_2
Skill_3
Skill_4
Skill_5
Skill_6
1
Mark
1
1
0
0
0
0
2
John
0
0
1
0
0
0
3
Doe
0
1
1
0
0
0
4
Jason
1
1
0
0
0
0
5
Kevin
1
1
0
0
0
0
6
Mike
0
1
1
0
0
1
Join the tables with a CASE expression in the ON clause:
SELECT DISTINCT s.skill_code
FROM TableSkills s INNER JOIN TableUsers u
ON 1 = CASE s.ID
WHEN 1 THEN u.Skill_1
WHEN 2 THEN u.Skill_2
WHEN 3 THEN u.Skill_3
WHEN 4 THEN u.Skill_4
WHEN 5 THEN u.Skill_5
WHEN 6 THEN u.Skill_6
END;
Or, with EXISTS, which may perform better:
SELECT s.skill_code
FROM TableSkills s
WHERE EXISTS (
SELECT *
FROM TableUsers u
WHERE 1 = CASE s.ID
WHEN 1 THEN u.Skill_1
WHEN 2 THEN u.Skill_2
WHEN 3 THEN u.Skill_3
WHEN 4 THEN u.Skill_4
WHEN 5 THEN u.Skill_5
WHEN 6 THEN u.Skill_6
END
);
See the demo.

finding records which doesnt have a state

AID
BID
STATE
1
1
1
1
2
3
1
3
3
2
1
0
2
2
3
2
3
3
3
1
3
3
2
0
3
3
3
I am trying to find AID records which doesnt have any 0 state in this example AID = 1 (will be multiple records)
If you would like to find all the AID with no 0 state records you may use
SELECT
AID
FROM
mytable
GROUP BY
AID
HAVING
COUNT(
CASE WHEN STATE=0 THEN 1 END
)=0;
AID
1
or if you would like to find all AID records where the state is not 0 for any AID record you may use the following.
SELECT
*
FROM
mytable
WHERE AID NOT IN (
SELECT AID FROM mytable WHERE STATE=0
)
AID
BID
STATE
1
1
1
1
2
3
1
3
3
Let me know if this works for you.

case when... for subgroups

I have table like this:
receipt
position
unit
booking time
1
1
1
08:00:00
1
2
1
08:00:05
1
3
1
08:00:11
1
4
1
08:00:18
1
5
1
08:00:21
1
6
5
08:00:25
1
1
1
08:00:30
1
2
1
08:00:33
1
3
1
08:00:37
1
4
1
08:00:40
1
5
1
08:00:49
2
1
1
08:01:55
2
2
1
08:01:58
2
3
1
08:02:04
3
1
1
08:02:20
3
2
5
08:02:24
3
1
1
08:02:30
3
2
1
08:02:35
I want to check for every receipt whether unit 5 exists or not. If unit 5 exists, I only want to select positions with a booking time after the entry with unit 5.
For the example above my result therefore should look like this:
receipt
position
unit
bookingtime
1
1
1
08:00:30
1
2
1
08:00:33
1
3
1
08:00:37
1
4
1
08:00:40
1
5
1
08:00:49
2
1
1
08:01:55
2
2
1
08:01:58
2
3
1
08:02:04
3
1
1
08:02:30
3
2
1
08:02:35
I have kind of a start, which delivers the right result if there was only one receipt:
Select * from test
where bookingtime> (case
when (select Max(bookingtime) from test where unit=5) is null
then (Select convert(time,'00:00:00'))
Else (select Max(bookingtime) from testdb where unit=5)
End)
What am I missing to let this code run through every single receipt separately so that I get the result I am looking for?
You can use a window function to get the time for unit 5:
select t.*
from (select t.*,
min(case when unit = 5 then bookingtime end) over (partition by receipt) as bookingtime_5
from t
) t
where bookingtime_5 is null or
bookingtime > bookingtime_5;

Sequence in SELECT statement

I need to create SELECT statement with sequence in Oracle. When col_flag is 1 then sequence increase with mod(col_seq, max_seq) and when col_flag is 0 then sequence don't increment.
Example:
col_group col_flag col_seq
--------- -------- --------
A 1 1
A 1 2
A 1 3
A 0 3
A 0 3
B 1 4
B 1 1
B 1 2
B 1 3
B 0 3
B 1 4
B 1 1
C 1 2
C 0 2
...
It guess that a window sum and arithmetics can do what you want - but you need a column that defines the ordering of the rows, I assumed id.
select col_flag,
mod(sum(col_flag) over(order by id), 4) + 1 col_seq
from mybltae

Using Row_Number to deal with non unique data

I have 4 columns a,b,c,d.
Some of my rows have the same values for all columns, is there any option to use row_number to insert same row number for those rows and continue counting if at least one of the values is different from values in the previous row
Example:
a b c d
1 1 1 1
1 1 1 1
1 1 1 2
1 1 1 2
1 1 1 3
1 1 1 3
1 1 2 4
I need it to look like: r=row_number
r a b c d
1 1 1 1 1
1 1 1 1 1
2 1 1 1 2
2 1 1 1 2
3 1 1 1 3
3 1 1 1 3
4 1 1 2 4
P.S. How to write here something like a table?
declare #t table(a int, b int, c int, d int)
insert #t values(1,1,1,1),(1,1,1,1),(1,1,1,2),
(1,1,1,2),(1,1,1,3),(1,1,1,3),(1,1,1,4)
select dense_rank() over(order by a,b,c,d) r, a,b,c,d from #t
Result:
r a b c d
1 1 1 1 1
1 1 1 1 1
2 1 1 1 2
2 1 1 1 2
3 1 1 1 3
3 1 1 1 3
4 1 1 1 4