MySQL: Expanding table with new rows including two table data - mysql

My table was enough to get what I needed at the beginning of the project but now I need to expand it.
Table s_ogr
id | ad | numara | yurt_id | egitim_id | yetkili_id | yetkili_ad
Current Table s_kontrol
id | ogr_id | tur_id | durum_id | tarih | egitim_id | yurt_id
What is needed s_kontrol_k
id | ogr_id | ogr_numara |ogr_ad | tur_id | durum_id | tarih | egitim_id | yurt_id
Explanation of rows ad = name , ogr_id is student_id , yurt_id is department_id
My Sittuation; s_kontrol is full of data over 24000. I need it to expand s_kontrol_k , but new two fields should be taken from s_ogr table , by the match operation of s_ogr and s_kontrol (s_ogr.id=s_kontrol.ogr_id and s_ogr.yurt_id =s_kontrol.yurt_id). I see that my mistake is not to add the ogr_id as id of student into s_kontrol
What I need; a Helpful query that copies the data from source but how to fill new fields from the third table with right values
INSERT INTO s_kontrol_k ( id , ogr_id , tur_id , durum_id , tarih , egitim_id , yurt_id )
SELECT id , ogr_id , tur_id , durum_id , tarih , egitim_id , yurt_id FROM s_kontrol
The queries that I am having a problem that is why I need a simple table
SELECT s_kontrol.ogr_id,
s_ogr.ad,
s_kontrol.tur_id,
s_kontrol.durum_id,
SUM(case s_kontrol.durum_id WHEN 1 THEN 1 else 0 end) var,
SUM(case s_kontrol.durum_id WHEN 2 THEN 1 else 0 end) gorevli,
SUM(case s_kontrol.durum_id WHEN 3 THEN 1 else 0 end) yok,
SUM(case s_kontrol.durum_id WHEN 4 THEN 1 else 0 end) izinli,
SUM(case s_kontrol.durum_id WHEN 5 THEN 1 else 0 end) hatimde
FROM s_kontrol, s_ogr
WHERE s_kontrol.ogr_id=s_ogr.numara
AND s_kontrol.yurt_id=s_ogr.yurt_id
and s_ogr.yurt_id=?
and tarih BETWEEN ? and ?
and tur_id IN (?)
GROUP BY s_kontrol.ogr_id
Second one
select deneme.ogr_id,
deneme.ad,
sum(case deneme.tur_id WHEN 1 THEN YUZDE else 0 END) sabah ,
sum(case deneme.tur_id WHEN 2 THEN YUZDE else 0 END) ogle,
sum(case deneme.tur_id WHEN 4 THEN YUZDE else 0 END) aksam,
sum(case deneme.tur_id WHEN 5 THEN YUZDE else 0 END) yatsi,
sum(case deneme.tur_id WHEN 6 THEN YUZDE else 0 END) sohbet,
sum(case deneme.tur_id WHEN 7 THEN YUZDE else 0 END) muhtelif
FROM (
SELECT s_kontrol.ogr_id,
s_ogr.ad,tur_id,
CEILING(((SUM(case s_kontrol.durum_id WHEN 1 THEN 1 else 0 end)
+SUM(case s_kontrol.durum_id WHEN 2 THEN 1 else 0 end)
+SUM(case s_kontrol.durum_id WHEN 3 THEN 1 else 0 end)
+SUM(case s_kontrol.durum_id WHEN 4 THEN 1 else 0 end)
+SUM(case s_kontrol.durum_id WHEN 5 THEN 1 else 0 end) )
-(SUM(case s_kontrol.durum_id WHEN 3 THEN 1 else 0 end)))
/(SUM(case s_kontrol.durum_id WHEN 1 THEN 1 else 0 end)
+SUM(case s_kontrol.durum_id WHEN 2 THEN 1 else 0 end)
+SUM(case s_kontrol.durum_id WHEN 3 THEN 1 else 0 end)
+SUM(case s_kontrol.durum_id WHEN 4 THEN 1 else 0 end)
+SUM(case s_kontrol.durum_id WHEN 5 THEN 1 else 0 end) )
* 100) YUZDE
FROM s_kontrol, s_ogr
WHERE s_kontrol.ogr_id=s_ogr.numara
and s_ogr.yurt_id=?
and tarih BETWEEN ? and ?
and tur_id IN(1,2,3,4,5,6,7)
GROUP BY s_kontrol.ogr_id,s_ogr.ad, tur_id
) deneme
group by ogr_id,ad order by 1

You can try something like below.
INSERT INTO s_kontrol_k
( id , ogr_id , ogr_ad , tur_id , durum_id , tarih , egitim_id , yurt_id )
SELECT o.id , o.ogr_id , o.ogr_ad ,
s.tur_id , s.durum_id , s.tarih , s.egitim_id , s.yurt_id
FROM
s_kontrol s inner join s_ogr o on o.yurt_id =s.yurt_id;
INSERT INTO s_kontrol_k (
id, ogr_id, ogr_numara, ogr_ad, tur_id,
durum_id, tarih, egitim_id, yurt_id)
SELECT
s_kontrol.id,
s_ogr.id,
s_kontrol.ogr_id,
s_ogr.ad,
s_kontrol.tur_id,
s_kontrol.durum_id,
s_kontrol.tarih,
s_kontrol.egitim_id,
s_kontrol.yurt_id FROM
s_kontrol inner join
s_ogr WHERE
s_ogr.yurt_id = s_kontrol.yurt_id
and s_ogr.numara = s_kontrol.ogr_id

First copied the same columns
INSERT INTO s_kontrol_k (
id, ogr_numara, tur_id, durum_id, tarih,
egitim_id, yurt_id)
SELECT
id,
ogr_id,
tur_id,
durum_id,
tarih,
egitim_id,
yurt_id
FROM
s_kontrol
Then Updated values
UPDATE
s_kontrol_k
INNER JOIN s_ogr ON s_kontrol_k.ogr_numara = s_ogr.numara
and s_kontrol_k.yurt_id = s_ogr.yurt_id SET s_kontrol_k.ogr_id = s_ogr.id
UPDATE
s_kontrol_k
INNER JOIN s_ogr ON s_kontrol_k.ogr_numara = s_ogr.numara
and s_kontrol_k.yurt_id = s_ogr.yurt_id SET
s_kontrol_k.ogr_ad = s_ogr.ad
Could be updated on main table by adding new rows

Related

SQL, sum inside of case condition

I'm trying to learn sql query and i want to solve the following problem.
Assume the table as follow:
id
schoolname
totalA
totalB
grade
1
school A
5
5
1
2
school A
5
5
2
3
school B
5
5
1
4
school B
5
5
2
Select schoolname
SUM(CASE WHEN (grade='1' ) THEN totalA ELSE 0 END) AS t1A,
SUM(CASE WHEN (grade='1' ) THEN totalB ELSE 0 END) AS t1B,
SUM(CASE WHEN (grade='2' ) THEN totalA ELSE 0 END) AS t2A,
SUM(CASE WHEN (grade='2' ) THEN totalB ELSE 0 END) AS t2B,
I would like to know if it is possible to add both totalA and B in one case condition.
I tried
Select schoolname
CASE WHEN (grade='1' ) THEN SUM(totalA+totalB) ELSE 0 END AS Grade 1,
CASE WHEN (grade='2' ) THEN SUM(totalA+totalB) ELSE 0 END AS Grade 2,
From school
Group By schoolname
But it give me error.
I want to achieve the following:
schoolname
grade 1
grade 2
School A
10
10
School B
10
10
Yes it is possible by group by query of MySQL in the same table.
For that you need to use this type of query:
SELECT schoolname,
SUM(CASE WHEN (grade = 1) THEN totalA + totalB ELSE 0 END) AS grade_1,
SUM(CASE WHEN (grade = 2) THEN totalA + totalB ELSE 0 END) AS grade_2
FROM school
GROUP BY schoolname

MySQL- Count total records based on different values of same column

I have a table as follows
table_user
id name status flag country
====================================================================================================
1 AB 1 0 US
2 BC 1 0 UK
3 CD 0 0 IN
4 DE 3 0 BR
5 EF 3 0 UK
6 FG 2 0 IN
7 GH 4 0 IN
I want to count the no. of records where
status = 1 as totalactiverecords,
status = 0 as totalinactiverecords,
status = 3 as totalrecentactiverecords,
status = 2 as totalemailnotverifiedrecords,
status = 4 as totalemailverifiedrecords,
, and country is UK, all in a single SELECT statement.
Is there any specific way to do it?
I have thought of something like
SELECT COUNT(*) as totalactiverecords WHERE status=1
COUNT(*) as totalinactiverecordsWHERE status=0,
COUNT(*) as totalemailnotverifiedrecords WHERE status=2,
COUNT(*) as totalrecentactiverecords WHERE status=3,
COUNT(*) as totalemailverifiedrecords WHERE status=4
FROM table_user where country=IN
,but that does not seem to work.
You can try this query:
SELECT count(case status when '1' then 1 else null end) as totalactiverecords,
count(case status when '0' then 1 else null end) as totalinactiverecords,
count(case status when '2' then 1 else null end) as totalemailnotverifiedrecords,
count(case status when '3' then 1 else null end) as totalrecentactiverecords,
count(case status when '4' then 1 else null end) as totalemailverifiedrecords
FROM table_user where country='IN'
I usually use CASE WHEN in this kind of problem:
SELECT sum(case when status = 1 then 1 end) as totalactiverecords,
COUNT sum(case when status = 0 then 1 end) as totalinactiverecords,
COUNT sum(case when status = 2 then 1 end) as totalemailnotverifiedrecord,
COUNT sum(case when status = 3 then 1 end) as totalrecentactiverecords,
COUNT sum(case when status = 4 then 1 end) as totalemailverifiedrecords
FROM table_user where country=IN

mysql - sums per month and year

i have an mysql table with the following structure:
tblapp
app_id app_date app_price app_price_paid payment_id receipt_id expenses_enabled
1 01/01/2000 100 50 1 1 1
1 11/01/2000 10 20 3 2 0
1 21/01/2000 40 40 1 4 0
1 30/01/2000 30 30 2 1 1
I would like to have as columns
YEAR DETAILS Jan Feb ... Dec TOTALS
and rows
1. Price = sum app_price where expenses_enabled=1
2. PricePaid = sum app_price_paid where expenses_enabled=1
3. No = sum app_price where expenses_enabled=1 and receipt_id=1
3. Yes = sum app_price where expenses_enabled=1 and receipt_id=0
Desire output:
Year Details Jan Feb ... Dec Totals
2020 Price 130 0 ... 0 130
2020 Price_Paid 80 0 ... 0 80
2020 No 80 0 ... 0 80
2020 Yes 0 0 ... 0 0
Is it possible.
Try this one:
select
y.year,
d.details,
sum(case when month(app_date) = 1 then val else 0 end) month_01,
sum(case when month(app_date) = 2 then val else 0 end) month_02,
sum(case when month(app_date) = 3 then val else 0 end) month_03,
sum(case when month(app_date) = 4 then val else 0 end) month_04,
sum(case when month(app_date) = 5 then val else 0 end) month_05,
sum(case when month(app_date) = 6 then val else 0 end) month_06,
sum(case when month(app_date) = 7 then val else 0 end) month_07,
sum(case when month(app_date) = 8 then val else 0 end) month_08,
sum(case when month(app_date) = 9 then val else 0 end) month_09,
sum(case when month(app_date) = 10 then val else 0 end) month_10,
sum(case when month(app_date) = 11 then val else 0 end) month_11,
sum(case when month(app_date) = 12 then val else 0 end) month_12,
sum(case when month(app_date) > 0 then val else 0 end) total
FROM (
SELECT 'Price' details UNION ALL
SELECT 'PricePaid' details UNION ALL
SELECT 'No' details UNION ALL
SELECT 'Yes' details
) d cross join (
SELECT distinct year(app_date) yr
FROM tblapp
) y
left join (
select app_date, COALESCE(app_price, 0) val, 'Price' details from tblapp
WHERE expenses_enabled = 1
union all
select app_date, COALESCE(app_price_paid, 0) val, 'PricePaid' details from tblapp
WHERE expenses_enabled = 1
union all
select app_date, COALESCE(app_price, 0) val, 'No' details from tblapp
WHERE expenses_enabled = 1 and receipt_id = 1
union all
select app_date, COALESCE(app_price, 0) val, 'Yes' details from tblapp
WHERE expenses_enabled = 1 and receipt_id = 0
) t on year(t.app_date) = y.year and t.details = d.details
group by y.year, d.details
order by y.year desc;

Is there a way to include the sum of all cases?

Given SQL: Is there a way to bring in the total of the result set?
SELECT
SUM(CASE
WHEN status = 3 THEN 1
ELSE 0
END) AS Open,
SUM(CASE
WHEN status = 4 THEN 1
ELSE 0
END) AS Close
FROM
Table1
WHERE
id = 2;
Result:
Open,Close
5,5
Desired Result:
Open,Close,Total
5,5,10
just add another case statement
SELECT
SUM(CASE
WHEN status = 3 THEN 1
ELSE 0
END) AS Open,
SUM(CASE
WHEN status = 4 THEN 1
ELSE 0
END) AS Close
SUM(CASE
WHEN status IN (3, 4) THEN 1
ELSE 0
END) AS Total
FROM
Table1
WHERE
id = 2;
You can use a CTE:
WITH sumCase AS (
SELECT
SUM(CASE
WHEN status = 3 THEN 1
ELSE 0
END) AS Open,
SUM(CASE
WHEN status = 4 THEN 1
ELSE 0
END) AS Close
FROM
Table1
WHERE
id = 2;)
SELECT Open,Close, Open + Close AS Total FROM Table1;
http://www.mysqltutorial.org/mysql-cte/
using sub-query
select open,close,open+close as total from
(
SELECT
SUM(CASE WHEN status = 3 THEN 1
ELSE 0
END ) AS Open,
SUM(CASE WHEN status = 4 THEN 1
ELSE 0
END) AS Close
FROM
Table1
WHERE id = 2 ) as T

MySQL optimize multiple subquery into nested inner join?

I have 3 tables; contracts, dealers, and users.
users have many dealers and dealers have many contracts but the contracts are not directly associated with the users.
I am trying to build a report that gets me a monthly count of completed contracts grouped by user for the last 12 months.
So far I have built a multiple subquery, which is very slow: SQL Fiddle
SELECT *,
( SELECT count(*) FROM contracts
WHERE
dealer_id IN
( SELECT id FROM dealers WHERE user_id = User.id )
AND status = 'Paid'
AND completion_date BETWEEN
'2012-08-01 00:00:00' AND '2012-08-31 23:59:59'
) AS Aug_2012,
( SELECT count(*) FROM contracts
WHERE
dealer_id IN
( SELECT id FROM dealers WHERE user_id = User.id )
AND status = 'Paid'
AND completion_date BETWEEN
'2012-09-01 00:00:00' AND '2012-09-30 23:59:59'
) AS Sep_2012
FROM users AS User
WHERE
id IN( SELECT user_id FROM dealers WHERE active = 1 AND user_id IS NOT NULL GROUP BY user_id )
AND id != 1
ORDER BY User.name ASC
Instead of the subquery which selects each month I'd like to use something like this:
COUNT(*) as last_12_months,
SUM(case when MONTH(completion_date) = 8 then 1 else 0 end) as Aug_2012,
SUM(case when MONTH(completion_date) = 9 then 1 else 0 end) as Sep_2012,
etc.
Since I'd be returning multiple columns I would have to restructure it, but I'm not sure how. If I use an INNER JOIN what clause do I join on?
Here's the final query based on Mikhail's answer below:
SELECT
User.*,
SUM(case when MONTH(completion_date) = 8 then 1 else 0 end) AS Aug_2012,
SUM(case when MONTH(completion_date) = 9 then 1 else 0 end) AS Sep_2012,
SUM(case when MONTH(completion_date) = 10 then 1 else 0 end) AS Oct_2012,
SUM(case when MONTH(completion_date) = 11 then 1 else 0 end) AS Nov_2012,
SUM(case when MONTH(completion_date) = 12 then 1 else 0 end) AS Dec_2012,
SUM(case when MONTH(completion_date) = 1 then 1 else 0 end) AS Jan_2013,
SUM(case when MONTH(completion_date) = 2 then 1 else 0 end) AS Feb_2013,
SUM(case when MONTH(completion_date) = 3 then 1 else 0 end) AS Mar_2013,
SUM(case when MONTH(completion_date) = 4 then 1 else 0 end) AS Apr_2013,
SUM(case when MONTH(completion_date) = 5 then 1 else 0 end) AS May_2013,
SUM(case when MONTH(completion_date) = 6 then 1 else 0 end) AS Jun_2013,
SUM(case when MONTH(completion_date) = 7 then 1 else 0 end) AS Jul_2013,
SUM(case when completion_date BETWEEN '2012-08-01 00:00:00' AND '2013-07-31 23:59:59' then 1 else 0 end) as last_12_months
FROM users AS User
LEFT OUTER JOIN
(
SELECT id, user_id FROM dealers
WHERE active = 1 AND user_id IS NOT NULL
) AS Dealer ON User.id = Dealer.user_id
LEFT OUTER JOIN
(
SELECT completion_date, status, dealer_id FROM contracts
WHERE completion_date BETWEEN '2012-08-01 00:00:00' AND '2013-07-31 23:59:59' AND status = 'Paid' AND cancelled = 0
) AS Contract on Dealer.id = Contract.dealer_id
WHERE
User.id IN
(
SELECT user_id FROM dealers
WHERE active = 1 AND user_id IS NOT NULL
GROUP BY user_id
)
GROUP BY
User.id order by User.name asc
This is about 4 times faster.
Try this:
select
User.id, User.name,
sum(case when MONTH(completion_date) = 8 and Year(completion_date)=2012 then 1 else 0 end) as Aug_2012,
sum(case when MONTH(completion_date) = 9 and Year(completion_date)=2012 then 1 else 0 end) as Sep_2012,
sum(case when MONTH(completion_date) = 10 and Year(completion_date)=2012 then 1 else 0 end) as Oct_2012,
sum(case when MONTH(completion_date) = 11 and Year(completion_date)=2012 then 1 else 0 end) as Nov_2012,
sum(case when MONTH(completion_date) = 12 and Year(completion_date)=2012 then 1 else 0 end) as Dec_2012,
sum(case when MONTH(completion_date) = 1 and Year(completion_date)=2013 then 1 else 0 end) as Jan_2012,
sum(case when MONTH(completion_date) = 2 and Year(completion_date)=2013 then 1 else 0 end) as Feb_2012,
sum(case when MONTH(completion_date) = 3 and Year(completion_date)=2013 then 1 else 0 end) as Mar_2012,
sum(case when MONTH(completion_date) = 4 and Year(completion_date)=2013 then 1 else 0 end) as Apr_2012,
sum(case when MONTH(completion_date) = 5 and Year(completion_date)=2013 then 1 else 0 end) as May_2012,
sum(case when MONTH(completion_date) = 6 and Year(completion_date)=2013 then 1 else 0 end) as Jun_2012,
sum(case when MONTH(completion_date) = 7 and Year(completion_date)=2013 then 1 else 0 end) as Jul_2012
from users AS User
left outer join dealers on
User.id=dealers.user_id
left outer join contracts on
dealers.id=contracts.dealer_id
group by
User.id,
contracts.status
having
contracts.status='Paid'
order by
User.name asc;