I have two SQL queries that I would like to join into one:
select d.full_month, COUNT(*) amount
from fact_ticket t
join dim_queue q on t.queue_id = q.queue_id
join vt_scopes s on t.scope_id = s.scope_id
join dim_date d on t.create_date_id = d.date_id
where q.name = 'Support'
and year(GETDATE()) = YEAR(t.create_date)
and s.statusname not in ('discarded', 'closed')
group by d.full_month
order by 1;
and
select d.full_month, COUNT(*) amount
from fact_ticket t
join dim_queue q on t.queue_id = q.queue_id
join vt_scopes s on t.scope_id = s.scope_id
join dim_date d on t.create_date_id = d.date_id
where q.name = 'Support'
and year(GETDATE()) = YEAR(t.create_date)
and s.statusname in ('closed')
group by d.full_month
order by 1;
Both gives me now a result with a date column and an amount column, but I would like to get everything in one query where I would get date, amount 1, amount 2.
Is there an easy to do this?
You can use below query-
SELECT d.full_month,
COUNT(IF(s.statusname NOT IN ('discarded', 'closed'),1,NULL)) amount1,
COUNT(IF(s.statusname IN ('closed'),1,NULL)) amount2
FROM fact_ticket t
JOIN dim_queue q ON t.queue_id = q.queue_id
JOIN vt_scopes s ON t.scope_id = s.scope_id
JOIN dim_date d ON t.create_date_id = d.date_id
WHERE q.name = 'Support'
AND YEAR(GETDATE()) = YEAR(t.create_date)
GROUP BY d.full_month
ORDER BY 1;
2nd Edition: Even you can get benefit of index if exist on create_date by below query-
SELECT d.full_month,
COUNT(IF(s.statusname NOT IN ('discarded', 'closed'),1,NULL)) amount1,
COUNT(IF(s.statusname IN ('closed'),1,NULL)) amount2
FROM fact_ticket t
JOIN dim_queue q ON t.queue_id = q.queue_id
JOIN vt_scopes s ON t.scope_id = s.scope_id
JOIN dim_date d ON t.create_date_id = d.date_id
WHERE q.name = 'Support'
AND t.create_date>= DATE_FORMAT(NOW(),'%Y-01-01 00:00:00') AND t.create_date <= DATE_FORMAT(NOW(),'%Y-12-31 23:59:59');
GROUP BY d.full_month
ORDER BY 1;
Another way using sum function
SELECT
d.full_month,
SUM(s.statusname NOT IN ('discarded', 'closed')) amount,
SUM(s.statusname = 'closed') amount_closed
FROM
fact_ticket t
JOIN dim_queue q
ON t.queue_id = q.queue_id
JOIN vt_scopes s
ON t.scope_id = s.scope_id
JOIN dim_date d
ON t.create_date_id = d.date_id
WHERE q.name = 'Support'
AND YEAR(GETDATE ()) = YEAR(t.create_date)
GROUP BY d.full_month
ORDER BY 1 ;
Related
I want to add a condition in the procedure, but I can't use (IF(Wh=0,'AND 1=1','AND D.wh_parn = 102'))
This is my procedure:
CREATE DEFINER=`akarremote`#`%` PROCEDURE `laporan_top_brand_penjualan`(IN Wh INT, IN `Datemin` VARCHAR(191), IN `Datemax` VARCHAR(191))
BEGIN
SELECT
A.item_id,
A.item_name AS ITEM,
(
SELECT
SUM( C.jumlah ) AS jumlah
FROM
mob_penjualan B
LEFT JOIN mob_penjualandetail C ON C.noTransaksi = B.noTransaksi
LEFT JOIN krd_wh D ON D.wh_id = B.idWH
WHERE
C.idItemProduk = A.item_id
AND B.TglTransaksi BETWEEN Datemin AND Datemax
(IF(Wh=0,'AND 1=1','AND D.wh_parn = 102'))
GROUP BY
C.idItemProduk
ORDER BY
jumlah DESC
) AS JML,
(
SELECT
SUM( C.qty ) AS qty
FROM
mob_penjualan B
LEFT JOIN mob_penjualandetail C ON C.noTransaksi = B.noTransaksi
LEFT JOIN krd_wh D ON D.wh_id = B.idWH
WHERE
C.idItemProduk = A.item_id
AND B.TglTransaksi BETWEEN Datemin AND Datemax
(IF(Wh=0,'AND 1=1','AND D.wh_parn = 102'))
GROUP BY
C.idItemProduk
ORDER BY
qty DESC
) AS QTY
FROM
krd_item A
ORDER BY
JML DESC, QTY DESC;
END
What's the solution?
WHERE C.idItemProduk = A.item_id
AND B.TglTransaksi BETWEEN Datemin AND Datemax
AND IF(Wh=0, 1, D.wh_parn = 102)
i am developing a LMS system for an institute
and i am trying to develop a recovery report on the end of month
the report contains student name total fee package, total received, total receiveable, current month pending installment
here is the installment data of a student with his admission id
and this is the ledger data from where ican pick the fee package and total receiveable fees
and i am using this query for recovery report
SELECT
SUM(l.dr)-SUM(l.cr) as sum_remaining,
f.dr as fee_package,
SUM(i.payment) as this_month_install,
a.reg_id, s.fname
FROM
ledger l, ledger f, student_data s,
admissions a LEFT OUTER JOIN installments i ON a.admissionid = i.admissionid
WHERE
a.admissionid = '58ac4b5421488' AND
a.reg_id = s.reg_id AND
l.reference = '58ac4b5421488' AND
l.details <> 'registration fee' AND
f.reference = '58ac4b5421488' AND
f.details = 'Fee Package' AND
i.install_no <> '1' AND
MONTH(i.pay_date) = '04' AND
YEAR(i.pay_date) = '2017'
GROUP BY a.admissionid
and its giving the result like this
but the result should be like
sum_remaining = 10000
and this_month_install = 10000
please help me to sort out this problem
Thanks in advance
you should start from admission and use inner join for the others table (left join for installments)
SELECT
SUM(l.dr)-SUM(l.cr) as sum_remaining,
f.dr as fee_package,
SUM(i.payment) as this_month_install,
a.reg_id,
s.fname
FROM admissions a
Inner JOIN ledger f ON f.reference = a.admissionid AND f.details = 'Fee Package'
INNER JOIN ledger l ON l.reference = a.admissionid AND l.details <> 'registration fee'
INNER JOIN student_data s ON a.reg_id = s.reg_id
LEFT JOIN installments i ON a.admissionid = i.admissionid AND i.install_no <> '1'
WHERE a.admissionid = '58ac4b5421488'
AND MONTH(i.pay_date) = '04'
AND YEAR(i.pay_date) = '2017'
GROUP BY a.admissionid
you have two row in installments table that match .. try filter just one
SELECT
SUM(l.dr)-SUM(l.cr) as sum_remaining,
f.dr as fee_package,
SUM(i.payment) as this_month_install,
a.reg_id,
s.fname
FROM admissions a
Inner JOIN ledger f ON f.reference = a.admissionid AND f.details = 'Fee Package'
INNER JOIN ledger l ON l.reference = a.admissionid AND l.details <> 'registration fee'
INNER JOIN student_data s ON a.reg_id = s.reg_id
LEFT JOIN installments i ON a.admissionid = i.admissionid
AND i.install_no not in ( '1', '2')
WHERE a.admissionid = '58ac4b5421488'
AND MONTH(i.pay_date) = '04'
AND YEAR(i.pay_date) = '2017'
GROUP BY a.admissionid
i have done this with a sub query
thanks all
select a.admissionid, s.fname,
sum(l.dr)-SUM(l.cr) as sum_remaining, i.*,
f.dr as fee_package from student_data s,
ledger l, ledger f, admissions a
RIGHT outer join (select admissionid,
sum(payment) as this_month_install
from
installments g where g.install_no <> '1' and MONTH(g.pay_date) = '04' and YEAR(g.pay_date) = '2017' group by g.admissionid) i
ON
i.admissionid = a.admissionid where a.reg_id = s.reg_id and
a.status = 'studying' and a.course = 'PH' and
a.campus = 'CIFSD01' and l.reference = a.admissionid and
l.details <> 'registration fee' and f.reference = a.admissionid
and f.details = 'Fee Package' GROUP BY a.std_id
I want to update column 'pagadas' from 'remisiones' with a calculated value from another 2 tables. My problem is I´m not be able to write the subtract into the inner join.
I´ve got this:
UPDATE remisiones AS r
INNER JOIN
(
SELECT remi, SUM(cantidad*precio) AS 'total'
FROM detalleremi
GROUP BY remi
)
AS d
ON r.id = d.remi
SET pagadas = 's'
WHERE d.total = 250000
This works too:
UPDATE remisiones AS r
INNER JOIN
(
SELECT remisionId, coalesce(SUM(cantidadp), 0) 'pagos'
FROM pagos
GROUP BY remisionId
)
AS d
ON r.id = d.remisionId
SET pagadas = 's'
WHERE d.pagos = 250000
But how can I subtract total - pagos ?
SELECT remi, SUM(cantidad*precio)
FROM detalleremi
GROUP BY remi -
SELECT remisionId, coalesce(SUM(cantidadp), 0)
FROM pagos
GROUP BY remisionId AS deuda
and set as:
SET pagadas = 's'
WHERE x.deuda = 0
Is this what you want?
UPDATE remisiones r INNER JOIN
(SELECT remi, SUM(cantidad*precio) as total
FROM detalleremi
GROUP BY remi
) d
ON r.id = d.remi INNER JOIN
(SELECT remisionId, coalesce(SUM(cantidadp), 0) as pagos
FROM pagos
GROUP BY remisionId
) p
ON r.id = p.remisionId
SET pagadas = 's'
WHERE d.total = p.pagos
I have a really long select from my database with many joins. The problem is with counting SUM: without sum, select time is about 3s, but with SUM is about 15s.
Is it possible to optimize my select to obtain a shorter select time?
Here is my code:
SELECT
accomodation.id,
accomodation.aid,
accomodation.title_en,
accomodation.title_url_en,
accomodation.address,
accomodation.zip,
accomodation.stars,
accomodation.picture,
accomodation.valid_from,
accomodation.valid_to,
accomodation.latitude,
accomodation.longitude,
accomodation.city_id AS
accomodation_city_id,
db_cities.id AS city_id,
db_cities.title_en AS city,
db_cities.title_url AS city_url,
db_countries.title_en AS country_title,
db_countries.title_url_en AS country_url,
accomodation_type.class AS accomodation_type_class,
accomodation_review_value_total.value AS review_total,
MIN(accomodation_price.price) AS price_from,
accomodation_rooms.total_persons
FROM
(SELECT aid, MAX(info_date_add) AS max_info_date_add FROM accomodation GROUP BY aid) accomodation_max
INNER JOIN accomodation
ON
accomodation_max.aid = accomodation.aid AND
accomodation_max.max_info_date_add = accomodation.info_date_add
LEFT JOIN db_cities
ON (
db_cities.id = accomodation.city_id OR
(((acos(sin((db_cities.latitude*pi()/180)) * sin((accomodation.latitude*pi()/180)) + cos((db_cities.latitude*pi()/180)) * cos((accomodation.latitude*pi()/180)) * cos(((db_cities.longitude - accomodation.longitude)*pi()/180))))*180/pi())*60*1.1515*1.609344) < '20')
JOIN db_countries
ON db_countries.id = accomodation.country_id
LEFT JOIN accomodation_review_value_total
ON accomodation_review_value_total.accomodation_aid = accomodation.aid
LEFT JOIN accomodation_type_value
ON accomodation_type_value.accomodation_id = accomodation.id
LEFT JOIN accomodation_type
ON accomodation_type.id = accomodation_type_value.accomodation_type_id
JOIN accomodation_season
ON (
accomodation_season.accomodation_aid = accomodation.aid AND
( '2013-11-04' BETWEEN accomodation_season.start_date AND accomodation_season.end_date OR '2013-11-05' BETWEEN accomodation_season.start_date AND accomodation_season.end_date ) )
JOIN accomodation_price
ON
accomodation_price.accomodation_aid = accomodation.aid AND
accomodation_price.accomodation_price_type_id = '1' AND
accomodation_price.accomodation_price_cat_id = '1' AND
accomodation_price.price BETWEEN '20' AND '250' AND
accomodation_price.accomodation_season_id = accomodation_season.id
JOIN accomodation_theme_value
ON accomodation_theme_value.accomodation_id = accomodation.id
INNER JOIN
(SELECT
accomodation_id,
SUM(accomodation_rooms.rooms) AS total_rooms,
SUM(accomodation_rooms.beds * accomodation_rooms.rooms) AS total_persons
FROM accomodation_rooms
GROUP BY accomodation_id) accomodation_rooms
ON
accomodation_rooms.accomodation_id = accomodation.id AND
accomodation_rooms.total_persons >= '4'
WHERE
db_countries.title_url_en LIKE '%spain%' AND
db_cities.title_url LIKE '%barcelona%' AND
accomodation_type_value.accomodation_type_id IN (5,10) AND
total_rooms >= '2' AND
accomodation_theme_value.accomodation_theme_id IN (11,12,13) AND
accomodation.stars IN (3,4,5) AND
( accomodation_review_value_total.value >= '4.5' ) AND
db_cities.id = '2416'
GROUP BY accomodation.aid
ORDER BY
CASE
WHEN accomodation.valid_to>=NOW() AND accomodation.valid_from<=NOW() AND MIN(accomodation_price.price) IS NOT NULL THEN 0
WHEN NOW()>accomodation.valid_to AND accomodation.valid_to>'0000-00-00' AND MIN(accomodation_price.price) IS NOT NULL THEN 1
WHEN accomodation.valid_to>=NOW() AND accomodation.valid_from<=NOW() THEN 2
WHEN NOW()>accomodation.valid_to AND accomodation.valid_to>'0000-00-00' THEN 3
ELSE 4 END,
review_total DESC,
accomodation.title_en
LIMIT 10
Hi I have run into a dilemma, I am doing this query:
SELECT GROUP_CONCAT(DISTINCT(ca.category_name) SEPARATOR ', ') AS categories, pr.promo_name, pr.add_value_text, c.contract_id, c.cmeal_plan, c.cmin_markup, c.civa, c.tax_include, c.hotel_id, hi.hname, hi.hstars, im.image_file, pl.plan_name, ra.price
FROM contracts AS c
INNER JOIN hotel_info AS hi ON hi.hotel_id = c.hotel_id AND hi.destination_id = '6460'
INNER JOIN images AS im ON im.foreign_id = hi.hotel_id
INNER JOIN meal_plan AS pl ON pl.plan_code = c.cmeal_plan AND pl.lang = '1'
INNER JOIN hotel_categories AS hc ON hc.hotel_id = hi.hotel_id
INNER JOIN categories AS ca ON ca.category_code = hc.category_code AND ca.lang = '1'
LEFT JOIN
(SELECT
r.hotel_id, AVG(r.double) AS price
FROM
rates AS r ) AS ra
ON ra.hotel_id = hi.hotel_id
LEFT JOIN promotions AS pr ON pr.hotel_id = hi.hotel_id AND FIND_IN_SET(c.contract_id, pr.contract_id) > 0 AND pr.book_start <= '2012-11-01' AND pr.book_end >= '2012-11-02' AND travel_start <= '2012-11-23' AND travel_end >= '2012-11-30' AND pr.lang = '1'
WHERE c.cstart <= '2012-11-01' AND c.cend >= '2012-11-01'
AND hi.status = '1'
AND im.type ='1'
GROUP BY hi.hotel_id
I am getting all the desired results except for the sub select query.. each hotel has a price but it is only giving me back one result and the rest are all null. Is there an error in my query? If any additional information is needed please let me know and thank you in advance for any help!
You are missing the GROUP BY in your subquery, so MySQL will only return one-value. If you want all hotel_id's then you need to GROUP BY that field:
SELECT GROUP_CONCAT(DISTINCT(ca.category_name) SEPARATOR ', ') AS categories,
pr.promo_name,
pr.add_value_text,
c.contract_id,
c.cmeal_plan,
c.cmin_markup,
c.civa,
c.tax_include,
c.hotel_id,
hi.hname,
hi.hstars,
im.image_file,
pl.plan_name,
ra.price
FROM contracts AS c
INNER JOIN hotel_info AS hi
ON hi.hotel_id = c.hotel_id
AND hi.destination_id = '6460'
INNER JOIN images AS im
ON im.foreign_id = hi.hotel_id
INNER JOIN meal_plan AS pl
ON pl.plan_code = c.cmeal_plan
AND pl.lang = '1'
INNER JOIN hotel_categories AS hc
ON hc.hotel_id = hi.hotel_id
INNER JOIN categories AS ca
ON ca.category_code = hc.category_code
AND ca.lang = '1'
LEFT JOIN
(
SELECT r.hotel_id, AVG(r.double) AS price
FROM rates AS r
GROUP BY r.hotel_id <-- add a GROUP BY hotel_id then you will get avg() for each hotel
) AS ra
ON ra.hotel_id = hi.hotel_id
LEFT JOIN promotions AS pr
ON pr.hotel_id = hi.hotel_id
AND FIND_IN_SET(c.contract_id, pr.contract_id) > 0
AND pr.book_start <= '2012-11-01'
AND pr.book_end >= '2012-11-02'
AND travel_start <= '2012-11-23'
AND travel_end >= '2012-11-30'
AND pr.lang = '1'
WHERE c.cstart <= '2012-11-01'
AND c.cend >= '2012-11-01'
AND hi.status = '1'
AND im.type ='1'
GROUP BY hi.hotel_id