How can show 0 in a repeated statement? - mysql

I'm trying to show all policy business units but is only showing when exist values
My tables:
|policies|
|id| |client| |policy_business_unit_id| |cia_ensure_id| |state|
1 MATT 1 1 0
2 STEVE 1 1 0
3 BILL 1 2 0
4 LARRY 1 2 1
5 MATT 1 2 1
6 STEVE 2 2 2
7 BILL 2 2 2
8 LARRY 2 2 1
9 MATT 2 1 1
|policy_business_units|
|id| |name| |comercial_area_id|
1 LIFE 1
2 ROB 1
3 CAR 1
4 RARE 1
5 RARE2 1
|comercial_areas|
|id| |name|
1 MICROSOFT
2 APPLE
|cia_ensures|
|id| |name|
1 ORANGE
2 BT
3 ATT
4 MOVISTAR
5 SPRINT
I'm getting this result it's ok but is not showing all policy_business units
UNIT V1 A1 N1 V2 A2 N2 V3 A3 N3 V4 A4 N4 V5 A5 N5
LIFE 2 0 0 1 2 0 0 0 0 0 0 0 0 0 0
ROB 0 1 0 0 1 2 0 0 0 0 0 0 0 0 0
Here is the query http://sqlfiddle.com/#!2/6909d8/1
set ##local.group_concat_max_len=10000;
select distinct #sql := concat('SELECT pb.name as unit,',
group_concat(concat(
'SUM(CASE WHEN p.state =0 AND ce.id=',id,' THEN 1 ELSE 0 END ) AS v',id,',
SUM(CASE WHEN p.state =1 AND ce.id=',id,' THEN 1 ELSE 0 END ) AS a',id,',
SUM(CASE WHEN p.state =2 AND ce.id=',id,' THEN 1 ELSE 0 END ) AS n',id)),
'
FROM cia_ensures ce
LEFT JOIN policies p on ce.id = p.cia_ensure_id
INNER JOIN policy_business_units pb ON pb.id = p.policy_business_unit_id
INNER JOIN comercial_areas ca ON ca.id = pb.comercial_area_id
AND ca.id=1
Group by p.policy_business_unit_id;')
from cia_ensures
where id in(1,2,3,4,5,6,7,8,10);
prepare stmt from #sql;
execute stmt;
I'm trying to show this:
UNIT V1 A1 N1 V2 A2 N2 V3 A3 N3 V4 A4 N4 V5 A5 N5
LIFE 2 0 0 1 2 0 0 0 0 0 0 0 0 0 0
ROB 0 1 0 0 1 2 0 0 0 0 0 0 0 0 0
RARE 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
RARE2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Please somebody can help me?
I will appreciate all help.

Please check below changes if it helps you, I did not execute it just do some changes in query, so need to check at your end:
set ##local.group_concat_max_len=10000;
select distinct #sql := concat('SELECT pb.name as unit,',
group_concat(concat(
'SUM(CASE WHEN p.state =0 AND ce.id=',id,' THEN 1 ELSE 0 END ) AS v',id,',
SUM(CASE WHEN p.state =1 AND ce.id=',id,' THEN 1 ELSE 0 END ) AS a',id,',
SUM(CASE WHEN p.state =2 AND ce.id=',id,' THEN 1 ELSE 0 END ) AS n',id)),
'
FROM
policy_business_units pb
LEFT JOIN policies p
ON pb.id = p.policy_business_unit_id
LEFT JOIN cia_ensures ce
on ce.id = p.cia_ensure_id
LEFT JOIN comercial_areas ca
ON ca.id = pb.comercial_area_id
AND ca.id=1
Group by pb.name;')
from cia_ensures
where id in(1,2,3,4,5,6,7,8,10);
prepare stmt from #sql;
execute stmt;

Related

How to combine/merge multiple queries in MySQL?

I cannot find similar question related specially to my case. So I post this question. And also ne need to provide sample data because below informations are enough.
My matches table is:
home_team_id
away_team_id
htft
11
9
2/2
18
17
X/2
20
19
2/2
1
8
X/2
4
12
1/X
14
2
2/2
3
16
1/1
13
15
2/X
7
10
1/1
5
6
1/1
9
13
1/1
and teams table is:
team_id
team_name
5
Arsenal
6
Aston Villa
7
Brentford
8
Brighton & Hove Albion
9
Burnley
12
Chelsea
19
Crystal Palace
18
Everton
20
Leeds United
31
Leicester City
32
Liverpool
I have 2 queries. One is show home matches count and second one is away team count results. There are working fine.
But how can I merge these two queries at one query?
My tables structures are;
teams table fields: team_id, team_name
matches table fields:  home_team_id, away.team_id, htft
Home Query:
SELECT m.home_team_id,t.team_name as Home,
SUM(CASE WHEN m.htft = '1/1' THEN 1 ELSE 0 END) AS '1/1',
SUM(CASE WHEN m.htft = 'X/1' THEN 1 ELSE 0 END) AS 'X/1',
SUM(CASE WHEN m.htft = 'X/X' THEN 1 ELSE 0 END) AS 'X/X',
SUM(CASE WHEN m.htft = '2/2' THEN 1 ELSE 0 END) AS '2/2',
SUM(CASE WHEN m.htft = 'X/2' THEN 1 ELSE 0 END) AS 'X/2',
SUM(CASE WHEN m.htft = '1/X' THEN 1 ELSE 0 END) AS '1/X',
SUM(CASE WHEN m.htft = '2/X' THEN 1 ELSE 0 END) AS '2/X',
SUM(CASE WHEN m.htft = '2/1' THEN 1 ELSE 0 END) AS '2/1',
SUM(CASE WHEN m.htft = '1/2' THEN 1 ELSE 0 END) AS '1/2'
FROM matches m, teams t
where m.home_team_id = t.team_id
GROUP BY m.home_team_id;
Output:
home_team_id
Home
1/1
X/1
X/X
2/2
X/2
1/X
2/X
2/1
1/2
5
Arsenal
1
0
0
0
0
0
0
0
0
7
Brentford
1
0
0
0
0
0
0
0
0
9
Burnley
1
0
0
0
0
0
0
0
0
18
Everton
0
0
0
0
1
0
0
0
0
20
Leeds United
0
0
0
1
0
0
0
0
0
Away Query:
SELECT m.away_team_id,t.team_name as Away,
SUM(CASE WHEN m.htft = '1/1' THEN 1 ELSE 0 END) AS '1/1',
SUM(CASE WHEN m.htft = 'X/1' THEN 1 ELSE 0 END) AS 'X/1',
SUM(CASE WHEN m.htft = 'X/X' THEN 1 ELSE 0 END) AS 'X/X',
SUM(CASE WHEN m.htft = '2/2' THEN 1 ELSE 0 END) AS '2/2',
SUM(CASE WHEN m.htft = 'X/2' THEN 1 ELSE 0 END) AS 'X/2',
SUM(CASE WHEN m.htft = '1/X' THEN 1 ELSE 0 END) AS '1/X',
SUM(CASE WHEN m.htft = '2/X' THEN 1 ELSE 0 END) AS '2/X',
SUM(CASE WHEN m.htft = '2/1' THEN 1 ELSE 0 END) AS '2/1',
SUM(CASE WHEN m.htft = '1/2' THEN 1 ELSE 0 END) AS '1/2'
FROM matches m, teams t
where m.away_team_id = t.team_id
GROUP BY m.away_team_id;
Output:
away_team_id
Away
1/1
X/1
X/X
2/2
X/2
1/X
2/X
2/1
1/2
6
Aston Villa
1
0
0
0
0
0
0
0
0
8
Brighton & Hove Albion
0
0
0
0
1
0
0
0
0
9
Burnley
0
0
0
1
0
0
0
0
0
12
Chelsea
0
0
0
0
0
1
0
0
0
19
Crystal Palace
0
0
0
1
0
0
0
0
0
How can I merge or combine both queries. I think if both queries possible to merge it will give the result I expected.
Thanks in advance to those who will help.
Expected result :
Team
HTFT(1/1)
HTFT(X/1)
HTFT(X/X)
HTFT(2/2)
HTFT(X/2)
HTFT(1/X)
HTFT(2/X)
HTFT(2/1)
HTFT(1/2)
Arsenal
2
1
0
1
1
2
1
0
1
Aston Villa
0
1
0
1
1
2
1
0
1
Everton
1
1
2
1
0
1
1
2
1
Current Home results Query
Current Away results Query

This says its having two 2bit inputs so how to find the truth table

Question 2
A logic circuit is given two 2-bit binary numbers A and B as its inputs. The circuit consists of two outputs Y1 and Y2. The output values of YI and Y2 are obtained as follows:
If A<B, then Y1 and Y2 will be equal to A-B. Else Y1 and Y2 will be equal to A
a) Determine the truth table for the system
b) Obtain the simplified:
i SOP for Y1 and Y2.
ii. POS expressions for YI
Truth Table:
A1 A2 A B1 B2 B A<B? Y1=Y2=A-B||A Y11-Y21 Y12=Y22 Y13=Y23
0 0 0 0 0 0 n 0 0 0 0
0 0 0 0 1 1 y -1 1 1 1
0 0 0 1 0 -1 n 0 0 0 0
0 0 0 1 1 -2 n 0 0 0 0
0 1 1 0 0 0 n 1 0 0 1
0 1 1 0 1 1 n 1 0 0 1
0 1 1 1 0 -1 n 1 0 0 1
0 1 1 1 1 -2 n 1 0 0 1
1 0 -1 0 0 0 y -1 1 1 1
1 0 -1 0 1 1 y -2 1 1 0
1 0 -1 1 0 -1 n -1 1 1 1
1 0 -1 1 1 -2 n -1 1 1 1
1 1 -2 0 0 0 y -2 1 1 0
1 1 -2 0 1 1 y -3 1 0 1
1 1 -2 1 0 -1 y -1 1 1 1
1 1 -2 1 1 -2 n -2 1 1 0
Y11-Y21 K-MAP (Karnaugh map):
A1A2\B1B2 0 0 0 1 1 1 1 0
0 0 0 1 0 0
0 1 0 0 0 0
1 0 1 1 1 1
1 1 1 1 1 1
Y11-Y21 Sum Of Products:
A1 V (A1' ^ A2' ^ B1' ^ B2)
Y11-Y21 Product Of Sums:
(A1 v A2')^(B1' v A1)^(A1 v B1 v B2)
The rest is left was an exercise or for another Answerer.

Counting number of '1' values in each bit position in Redshift column

I have BIGINT column in my Redshift table, and I want a query that will:
Count how many times the value '1' appears in each bit position across the binary value in all the rows of this column
Will show it in a way that I'll be able to take the x top bits_positions.
For example (I'm already writing the integer values as binary to simplify the example):
column
--------
11011110 = 222
00000000 = 0
11111100 = 252
00011000 = 24
11111100 = 252
00011000 = 24
11000010 = 194
76543210 <- bit_position
will return a table like:
bit_position count
0 0
1 2
2 3
3 5
4 5
5 2
6 4
7 4
In this case I'll be able to get the top five bit_position: (3,4,6,7,2)
Note: I'll might have up to 64 bit_positions for a column.
You can use a bit-wise AND & to check for each position.
Here's an example going across rows:
SELECT SUM(CASE WHEN bit_col & 64 > 0 THEN 1 ELSE 0 END) "1000000"
, SUM(CASE WHEN bit_col & 32 > 0 THEN 1 ELSE 0 END) "0100000"
, SUM(CASE WHEN bit_col & 16 > 0 THEN 1 ELSE 0 END) "0010000"
, SUM(CASE WHEN bit_col & 8 > 0 THEN 1 ELSE 0 END) "0001000"
, SUM(CASE WHEN bit_col & 4 > 0 THEN 1 ELSE 0 END) "0000100"
, SUM(CASE WHEN bit_col & 2 > 0 THEN 1 ELSE 0 END) "0000010"
, SUM(CASE WHEN bit_col & 1 > 0 THEN 1 ELSE 0 END) "0000001"
FROM my_table
;
1000000 | 0100000 | 0010000 | 0001000 | 0000100 | 0000010 | 0000001
---------+---------+---------+---------+---------+---------+---------
11 | 8 | 11 | 13 | 11 | 9 | 8
To have the results in a single column you need to use union:
SELECT 1 AS "col", SUM(CASE WHEN bit_col & 64 > 0 THEN 1 ELSE 0 END) AS bit_count FROM my_table
UNION ALL SELECT 2 AS "col", SUM(CASE WHEN bit_col & 32 > 0 THEN 1 ELSE 0 END) AS bit_count FROM my_table
UNION ALL SELECT 3 AS "col", SUM(CASE WHEN bit_col & 16 > 0 THEN 1 ELSE 0 END) AS bit_count FROM my_table
UNION ALL SELECT 4 AS "col", SUM(CASE WHEN bit_col & 8 > 0 THEN 1 ELSE 0 END) AS bit_count FROM my_table
UNION ALL SELECT 5 AS "col", SUM(CASE WHEN bit_col & 4 > 0 THEN 1 ELSE 0 END) AS bit_count FROM my_table
UNION ALL SELECT 6 AS "col", SUM(CASE WHEN bit_col & 2 > 0 THEN 1 ELSE 0 END) AS bit_count FROM my_table
UNION ALL SELECT 7 AS "col", SUM(CASE WHEN bit_col & 1 > 0 THEN 1 ELSE 0 END) AS bit_count FROM my_table
ORDER BY bit_count DESC
;
position | bit_count
----------+-----------
6 | 6
7 | 6
4 | 4
5 | 4
2 | 0
3 | 0
1 | 0
http://docs.aws.amazon.com/redshift/latest/dg/r_OPERATOR_SYMBOLS.html
EDIT: If you would like something more dynamic you will need to look into using a UDF. You could start with my f_bitwise_to_string UDF as a template and add what you need from there. https://github.com/awslabs/amazon-redshift-udfs/blob/master/scalar-udfs/f_bitwise_to_string.sql

How to make Recursive Query in sql Server 2008

I need to calculate the value of indebtedness column so that when openingBalance !=0 then indebtedness = openingBalnce+SalesTotal-SalesReturn. But, when openingBalnce = 0 then indebtedness = indebtedness of the previous monthSales with the same SalesID. If the previous value = 0 get the previous value and continue get previous value till have value in this column:
SalesMonth SalesID openingBalance SalesTotal SalesReturn Indebtednes
---------- ------- -------------- ---------- ----------- ------------
1 1 352200 0 5600 Null
------------------------------------------------------------------------
1 2 50000 1100 0 Null
------------------------------------------------------------------------
1 3 9500 6000 0 Null
------------------------------------------------------------------------
2 1 0 0 1200 Null
------------------------------------------------------------------------
2 2 0 300 0 Null
------------------------------------------------------------------------
2 3 0 500 1000 Null
------------------------------------------------------------------------
3 1 0 600 0 NULL
------------------------------------------------------------------------
3 2 0 200 0 NULL
-----------------------------------------------------------------------
3 3 0 0 10 NULL
-----------------------------------------------------------------------
.
.
.
12 1 0 0 0 NULL
----------------------------------------------------------------------
12 2 0 0 0 NULL
----------------------------------------------------------------------
12 3 0 0 0 NULL
And Output like this:
when openingBalance !=0 then Indebtednes=openingBalnce+SalesTotal-SalesReturn
when openingBalnce =0 then Indebtednes=Indebtednes (of the previous
month of the same SalesID)+SalesTotal-SalesReturn.
And this is the output i want.
SalesMonth SalesID openingBalance SalesTotal SalesReturn Indebtednes
---------- ------- -------------- ---------- ----------- ------------
1 1 352200 0 5600 346600
------------------------------------------------------------------------
1 2 50000 1100 0 51100
------------------------------------------------------------------------
1 3 9500 6000 0 15500
------------------------------------------------------------------------
2 1 0 0 1200 345400
------------------------------------------------------------------------
2 2 0 300 0 51400
------------------------------------------------------------------------
2 3 0 500 1000 15000
------------------------------------------------------------------------
3 1 0 600 0 346000
------------------------------------------------------------------------
3 2 0 200 0 51600
-----------------------------------------------------------------------
3 3 0 0 10 14990
-----------------------------------------------------------------------
.
.
.
12 1 0 0 0 NULL
----------------------------------------------------------------------
12 2 0 0 0 NULL
----------------------------------------------------------------------
12 3 0 0 0 NULL
you could try like below cte query
declare #tb table(SalesMonth int,SalesID int,
openingBalance money,SalesTotal money,SalesReturn money,Indebtednes money)
insert into #tb(SalesMonth,SalesID,openingBalance,SalesTotal,SalesReturn,Indebtednes)
values (1,1,352200,0,5600,Null)
,(1,2,50000,1100,0,Null)
,(1,3,9500,6000,0,Null)
,(2,1,0,0,1200,Null)
,(2,2,0,300,0,Null)
,(2,3,0,500,1000,Null)
,(3,1,0,600,0,NULL)
,(3,2,0,200,0,NULL)
,(3,3,0,0,10,NULL)
;with t1 as (select *, row_number() over
(order by salesid,SalesMonth) as rno from #tb),
t2(inde,rno,salid,mnth)as
(select case when openingBalance !=0 then
openingBalance+SalesTotal-SalesReturn
when openingBalance =0 then 0 end as inde,
rno,SalesID,SalesMonth from t1 where rno=1
union all
select case when openingBalance !=0 then
openingBalance+SalesTotal-SalesReturn
when openingBalance =0 then
case when SalesID=salid then inde+SalesTotal-SalesReturn
else 0 end end,
t1.rno,t1.SalesID,SalesMonth from t2 join t1 on t2.rno+1=t1.rno )
select SalesMonth,SalesID,openingBalance,
SalesTotal,SalesReturn,inde as Indebtednes from t1
inner join t2 on t1.SalesID=t2.salid and
t1.SalesMonth=t2.mnth order by mnth,salid

Find Average Mark For Each User - Mysql

First table :
UserId UserName
1 User1
2 User2
3 User3
4 User4
Second Table
Userid Mark Aptitude English Technical Status
1 40 1 0 0 S
1 30 0 1 0 F
2 60 0 0 1 S
2 75 0 1 0 F
2 25 0 1 0 F
3 45 1 0 0 F
3 45 1 0 0 D
3 50 0 0 1 F
3 50 0 0 1 F
I have this two table. I need a query to get the each user average mark in English, Aptitude and Technical. The average should be calculated only for status F. The result should be like this
UserId AptitudeAverage EnglishAverage TechnicalAverage
1 0 30 0
2 0 50 0
3 45 0 50
4 0 0 0
Try this:-
SELECT userID, IFNULL(AVG(case when Aptitude = 1 then Mark * Aptitude end), 0) AS AptitudeAverage,
IFNULL(AVG(case when English = 1 then Mark * English end), 0) AS EnglishAverage,
IFNULL(AVG(case when Technical = 1 then Mark * Technical end), 0) AS TechnicalAverage
FROM YOUR_TAB
WHERE Status = 'F'
GROUP BY userID;
This might help you.
Here is the fiddle.
http://sqlfiddle.com/#!9/e449f/21