optimize this query - sql-server-2008

ms sql server 2008
SELECT Action.*
FROM Mailing
INNER JOIN ActionCategoryMailingBunch
ON Mailing.MailingID = ActionCategoryMailingBunch.MailingID
INNER JOIN ActionCategory
ON ActionCategoryMailingBunch.ActionCategoryID =
ActionCategory.ActionCategoryID
INNER JOIN Action
ON ActionCategory.ActionCategoryID = Action.ActionCategoryID
WHERE ( Mailing.MailingID = 7 )
AND ( Mailing.MailingID NOT IN (SELECT MailingID
FROM MailingReport) )
AND ( Action.ActionID NOT IN (SELECT ActionID
FROM MailingReport) )
AND ( ActionCategoryMailingBunch.MailingBunchStatusID = 4 )
especially this block
(Mailing.MailingID NOT IN (SELECT MailingID FROM MailingReport))
AND (Action.ActionID NOT IN (SELECT ActionID FROM MailingReport))

Add the below code in the select statement
Left Join MailingReport MR on MR.ActionID = Mailing.MailingID
Add the below code in Where clause
(MR.ActionID is null)
Performance upgrade due to following block
(Mailing.MailingID NOT IN (SELECT MailingID FROM MailingReport))
Final Query
SELECT Action.*
FROM Mailing
INNER JOIN ActionCategoryMailingBunch
ON Mailing.MailingID = ActionCategoryMailingBunch.MailingID
INNER JOIN ActionCategory
ON ActionCategoryMailingBunch.ActionCategoryID =
ActionCategory.ActionCategoryID
INNER JOIN Action
ON ActionCategory.ActionCategoryID = Action.ActionCategoryID
Left Join MailingReport MR on MR.ActionID = Mailing.MailingID
WHERE ( Mailing.MailingID = 7 )
--AND ( Mailing.MailingID NOT IN (SELECT MailingID
-- FROM MailingReport) )
AND
(MR.ActionID is null)
AND ( Action.ActionID NOT IN (SELECT ActionID
FROM MailingReport) )
AND ( ActionCategoryMailingBunch.MailingBunchStatusID = 4 )
Similarly you can do for the second block
Performance due to second block
AND (Action.ActionID NOT IN (SELECT ActionID FROM MailingReport))
Final Query for both blocks
SELECT Action.*
FROM Mailing
INNER JOIN ActionCategoryMailingBunch
ON Mailing.MailingID = ActionCategoryMailingBunch.MailingID
INNER JOIN ActionCategory
ON ActionCategoryMailingBunch.ActionCategoryID =
ActionCategory.ActionCategoryID
INNER JOIN Action
ON ActionCategory.ActionCategoryID = Action.ActionCategoryID
Left Join MailingReport MR on MR.ActionID = Mailing.MailingID
Left Join MailingReport MRA on MRA.ActionID = Action.ActionID
WHERE ( Mailing.MailingID = 7 )
AND
(MR.ActionID is null)
AND
(MRA.ActionID is null)
AND ( ActionCategoryMailingBunch.MailingBunchStatusID = 4 )

Related

how to limit record in left join

SELECT commerce_product_field_data_commerce_product__field_data_field_products.entity_id, field_products_commerce_product.nid FROM commerce_order o
join commerce_payment_transaction t on o.order_id = t.order_id
join commerce_line_item i on o.order_id = i.order_id
LEFT JOIN field_data_commerce_total s ON i.line_item_id = s.entity_id AND (s.entity_type = 'commerce_line_item' AND s.deleted = '0')
LEFT JOIN field_data_commerce_product field_data_commerce_product ON i.line_item_id = field_data_commerce_product.entity_id AND (field_data_commerce_product.entity_type = 'commerce_line_item' AND field_data_commerce_product.deleted = '0')
INNER JOIN commerce_product commerce_product_field_data_commerce_product ON field_data_commerce_product.commerce_product_product_id = commerce_product_field_data_commerce_product.product_id
LEFT JOIN
(select * from field_data_field_products)
commerce_product_field_data_commerce_product__field_data_field_products ON commerce_product_field_data_commerce_product.product_id = commerce_product_field_data_commerce_product__field_data_field_products.field_products_product_id
LEFT JOIN ( select nid as nid from node order by nid)
field_products_commerce_product
ON commerce_product_field_data_commerce_product__field_data_field_products.entity_id = field_products_commerce_product.nid LEFT JOIN (
select r.entity_id, r.field_ranges_value from field_data_field_ranges r
) r
on r.entity_id = field_products_commerce_product.nid
WHERE t.status = 'success' and i.type = 'product' and o.Uid <> 0
AND o.status IN ('completed') and o.created >= '1483228800' and o.created <= '1483315200' and r.field_ranges_value = 'Tasty Sticks'
Is my sql
It is giving me 5 results. I only need 4
One of the product id's belong to two Drupal nodes and I only want one of them
I tried changing LEFT JOIN ( select nid as nid from node order by nid) to
LEFT JOIN ( select nid as nid from node order by nid limit 1) but then I don't get any records at all. Any idea what needs changing please other than removing one of the duplicate nodes. Thanks

How can I speed up this query with mysqli?

I have this query and it take 117 seconds to get 100000 rows can me get all this rows on 5 seconds or 10 seconds?
SELECT
`nas`.`nasname`,
`nas`.`api_username`,
`nas`.`api_password`,
`nas`.`api_port`,
`nas`.`secret`,
`nas`.`up_by`,
COALESCE(`nas`.`api_is_enabled`,'0') as `api_is_en`,
`radacct`.`nasipaddress`,
`radcheck`.`address_list_name`,
`radcheck`.`address_val`,
`radacct`.`framedipaddress`,
`radacct`.`callingstationid`,
`radacct`.`radacctid` as `id_session`,
`radacct`.`framedprotocol`,
`radacct`.`username`,
`radacct`.`last_speed` ,
`radacct`.`acctsessionid` as `acctsessionid`,
`radip`.`value` as `ip_address`,
`radmac`.`value` as `mac_address`,
`radcount`.`value` as `simul_sess`,
COUNT(`radacct`.`radacctid`) as count_login ,
COALESCE(`card_users`.`id`,0) as `id_card`,
COALESCE(`card_users`.`download_qouta`,`userinfo`.`in_down`) *1024*1024 as `down_qouta`,
COALESCE(`card_users`.`upload_qouta`,`userinfo`.`in_up`) *1024*1024 as `up_qouta`,
COALESCE(`card_users`.`all_quota`,`userinfo`.`av_qouta`) *1024*1024 as `av_qouta`,
`card_users`.`date_end_card` as `date_end_card`,
`card_users`.`val_date` as `val_date`,
`card_users`.`per_second` as `per_second`,
`card_users`.`at_the_first_login` as `at_the_first_login`,
`card_users`.`exp_first_login` as `exp_first_login`,
`card_users`.`val_time_exp` as `val_time_exp`,
`card_users`.`time_cards_exp` as `time_cards_exp`,
`card_users`.`exp_quota` as `exp_quota`,
`card_users`.`exp_date` as `exp_date`,
`userinfo`.`updatedate` as `updatedate`,
`userinfo`.`divi_down_speed_slm` as `divi_down_speed_slm`,
`userinfo`.`divi_up_speed_slm` as `divi_up_speed_slm`,
`userinfo`.`arr_days` as `u_arr_days`,
`userinfo`.`value_choice` as `u_value_choice`,
`userinfo`.`last_end_day` as `last_end_day`,
`userinfo`.`macs` as `macs`,
`p`.`profile_name` as `profile_name`,
`p`.`daily_down_qouta`*1024*1024 as `down_daily_qouta`,
`p`.`daily_up_qouta`*1024*1024 as `up_daily_qouta`,
`p`.`daily_profile_qouta`*1024*1024 as `daily_profile_qouta`,
`p`.`online_time` as `online_time`,
`p`.`hours_min` as `hours_min`,
`p`.`daily_online_time` as `daily_online_time`,
`p`.`daily_hours_min` as `daily_hours_min`,
`p`.`bandwidth_time` as `bandwidth_time`,
`p`.`daily_expire_service` as `daily_expire_service`,
`p`.`qouta_expire_service` as `qouta_expire_service`,
`p`.`profile_expire_service` as `profile_expire_service`,
`p`.`sp_up` as `sp_up`,
`p`.`sp_down` as `sp_down`,
`p`.`ch_day_end` as `ch_day_end`,
`p`.`set_day_end` as `set_day_end`,
`p`.`percent` as `percent`,
`p`.`arr_days` as `p_arr_days`,
`p`.`value_choice` as `p_value_choice`,
`r1`.`value` as `value_exp`,
`p1`.`bandwidth_time` as `band_exp`,
`p1`.`percent` as `percent_exp`,
`r2`.`value` as `val_address_exp_list`,
`r3`.`value` as `value_exp_daily`,
`p3`.`bandwidth_time` as `band_daily_exp`,
`p3`.`percent` as `percent_daily_exp`,
`r4`.`value` as `val_address_exp_daily_list`,
`r5`.`value` as `value_exp_serv`,
`p3`.`bandwidth_time` as `band_serv_exp`,
`p3`.`percent` as `percent_serv_exp`,
`r6`.`value` as `val_address_exp_serv_list`,
`r7`.`value` as `value_now`,
`r8`.`value` as `val_address_list`,
COALESCE(ROUND(time_to_sec(`userinfo`.`online_time`)),0) as `t_online_time` ,
COALESCE(ROUND(time_to_sec(`userinfo`.`daily_online_time`)),0) as `d_online_time`,
UNIX_TIMESTAMP(STR_TO_DATE(`radexp`.`value`, '%d %b %Y %H:%i')) as `exp_user`,
`radacct`.`callingstationid` as `callingstationid`,
UNIX_TIMESTAMP(STR_TO_DATE(`radacct`.`acctstarttime`, '%Y-%m-%d %H:%i:%s')) as `session_st_date`
FROM `radacct`
INNER JOIN `radcheck`
ON `radacct`.`username` = `radcheck`.`username`
AND `radcheck`.`attribute` = 'Cleartext-Password'
INNER JOIN `radusergroup` `r9`
ON `r9`.`username` = `radcheck`.`username`
LEFT JOIN `userinfo`
ON `userinfo`.`username` = `r9`.`username`
LEFT JOIN (
SELECT SUM(`radacct`.`acctinputoctets`) as `up_today`
, SUM(`radacct`.`acctoutputoctets`) as `down_today`
, SUM(`radacct`.`acctsessiontime`) as `daily_time`
, `radacct`.`username`
FROM `radacct`
WHERE DATE_FORMAT(STR_TO_DATE(`acctstarttime`,'%Y-%m-%d %H:%i:%s'),'%Y-%m-%d') = DATE_FORMAT(NOW(),'%Y-%m-%d')
GROUP BY `username`
) as `rad2`
ON `rad2`.`username` = `r9`.`username`
INNER JOIN `nas`
ON `nas`.`nasname`=`radacct`.`nasipaddress`
LEFT JOIN `profiles` `p`
ON `p`.`profile_name` = `r9`.`groupname`
LEFT JOIN `profiles` `p1`
ON `p1`.`id` = `p`.`qouta_expire_service`
LEFT JOIN `profiles` `p2`
ON `p2`.`id` = `p`.`daily_expire_service`
LEFT JOIN `profiles` `p3`
ON `p3`.`id` = `p`.`profile_expire_service`
LEFT JOIN `radgroupreply` `r1`
ON `r1`.`groupname` = `p1`.`profile_name`
AND `r1`.`attribute` = 'Mikrotik-Rate-Limit'
LEFT JOIN `radgroupreply` `r2`
ON `r2`.`groupname` = `p1`.`profile_name`
AND `r2`.`attribute` = 'Mikrotik-Address-List'
LEFT JOIN `radgroupreply` `r3`
ON `r3`.`groupname` = `p2`.`profile_name`
AND `r3`.`attribute` = 'Mikrotik-Rate-Limit'
LEFT JOIN `radgroupreply` `r4`
ON `r4`.`groupname` = `p2`.`profile_name`
AND `r4`.`attribute` = 'Mikrotik-Address-List'
LEFT JOIN `radgroupreply` `r5`
ON `r5`.`groupname` = `p3`.`profile_name`
AND `r5`.`attribute` = 'Mikrotik-Rate-Limit'
LEFT JOIN `radgroupreply` `r6`
ON `r6`.`groupname` = `p3`.`profile_name`
AND `r6`.`attribute` = 'Mikrotik-Address-List'
LEFT JOIN `radgroupreply` `r7`
ON `r7`.`groupname` = `p`.`profile_name`
AND `r7`.`attribute` = 'Mikrotik-Rate-Limit'
LEFT JOIN `radgroupreply` `r8`
ON `r8`.`groupname` = `p`.`profile_name`
AND `r8`.`attribute` = 'Mikrotik-Address-List'
LEFT JOIN `card_users`
ON `card_users`.`id` = `radcheck`.`id_card`
LEFT JOIN `radreply` as `radip`
ON `radip`.`username` = `r9`.`username`
AND `radip`.`attribute`='Framed-IP-Address'
LEFT JOIN `radcheck` as `radmac`
ON `radmac`.`username` = `r9`.`username`
AND `radmac`.`attribute`='Calling-Station-Id'
LEFT JOIN `radcheck` as `radcount`
ON `radcount`.`username` = `r9`.`username`
AND `radcount`.`attribute`='Simultaneous-Use'
LEFT JOIN `radcheck` as `radexp`
ON `radexp`.`username` = `r9`.`username`
AND `radexp`.`attribute`='Expiration'
WHERE ( radacct .AcctStopTime IS NULL
OR radacct.AcctStopTime = '0000-00-00 00:00:00')
GROUP BY `radacct`.`username`
When remove this from query it speed up 60%
LEFT JOIN (SELECT SUM(`radacct`.`acctinputoctets`) as `up_today`,
SUM(`radacct`.`acctoutputoctets`) as `down_today`,
SUM(`radacct`.`acctsessiontime`) as `daily_time`,
`radacct`.`username` FROM `radacct`
WHERE DATE_FORMAT(STR_TO_DATE(`acctstarttime`,'%Y-%m-%d %H:%i:%s'),'%Y-%m-%d') = DATE_FORMAT(NOW(),'%Y-%m-%d')
GROUP BY `username`) as `rad2` ON (`rad2`.`username` = `r9`.`username`)
I have index for all this tables so what is my problem ?
Note : I have pc have
cpu core i 5
ram 4 giga
this image for explain my table

Only getting one result from sub select in inner join in mysql

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

Using JOIN sql query

I would like to use JOIN instead of IN in the following SQL query. I can't figure out how to do it.
SELECT * FROM shop_orders WHERE
id IN (SELECT orders_id FROM shop_orders_data WHERE closed='1' /*AND backorder='0'*/ AND exhibition_id='389' AND
exhibition_id IN (SELECT id FROM shop_exhibitions WHERE
country_id IN (SELECT id FROM countries WHERE id='72')) AND in_country = '72' AND
exhibition_id IN (SELECT id FROM shop_exhibitions WHERE start<=1336946400 AND end>1336600800)) AND
id IN (SELECT orders_id FROM shop_orders_products WHERE
products_id IN (SELECT id FROM shop_products WHERE artno='120000' OR name LIKE '%120000%')) AND created>=1333231200 AND created<1333663200 ORDER BY created DESC
I tried this:
SELECT
s.*
FROM
shop_orders s
INNER JOIN shop_orders_data od ON s.id=od.orders_id
INNER JOIN shop_exhibitions se ON od.exhibition_id=se.id
INNER JOIN countries co ON se.country_id=co.id
INNER JOIN shop_orders_products sop ON s.id=sop.orders_id
INNER JOIN shop_products sp
ON sop.products_id=sp.id
WHERE od.closed=1
AND ( sp.artno='120000' or sp.name LIKE '%120000%' )
AND ( od.exhibition_id='389')
AND ( od.in_country = '72')
AND ( se.start <=1336946400)
AND ( se.end >1336600800)
AND ( se.created>=1333231200)
AND ( se.created<1333663200)
ORDER BY `s`.`created` DESC
I this correct??
See if this works (and study the code to learn how it works):
SELECT *
FROM shop_orders so
JOIN shop_orders_data sod ON (
(so.id = sod.orders_id)
AND (sod.closed = '1')
/*AND (sod.backorder = '0') */
AND (sod.exhibition_id = '389')
AND (sod.in_country = '72')
)
JOIN shop_exhibitions se ON (
(sod.exhibition_id = se.id)
AND (se.start <= 1336946400)
AND (se.end > 1336600800)
)
JOIN countries c ON (
(se.country_id = c.id)
AND (c.id = '72')
)
JOIN shop_orders_products sop ON (
(so.id = sop.orders_id)
)
JOIN shop_products sp ON (
(sop.products_id = sp.id)
AND ((sp.artno='120000') OR (sp.name LIKE '%120000%'))
)
WHERE (so.created >= 1333231200) AND (so.created < 1333663200)
ORDER BY so.created DESC;
The join syntax works like this:
SELECT field1,field2,field3
FROM FirstTable
JOIN SecondTable ON (FirstTable.PrimaryKey = SecondTable.ForeignKey)
JOIN ThirdTable ON (FirstTable.PrimaryKey = ThirdTable.ForeignKey)
Try applying this approach to your query.

Suggestions on complex sql statement

SELECT `v`.*
, GROUP_CONCAT(DISTINCT(`gg`.genre_id)) AS `genre_ids`
, GROUP_CONCAT(DISTINCT(`gg`.genre_ru)) AS `genres`
, GROUP_CONCAT(DISTINCT(`tg`.tag_id)) AS `tags_ids`
, GROUP_CONCAT(DISTINCT(`tg`.name)) AS `tags`
FROM `video` AS `v`
LEFT JOIN `video_categories` AS `gc` ON gc.video_id = v.video_id
LEFT JOIN `video_genres` AS `gg` ON gg.genre_id = gc.genre_id
LEFT JOIN `tags_relations` AS `tr` ON tr.department=18 AND tr.parent_id = v.video_id
LEFT JOIN `tags` AS `tg` ON tg.tag_id = tr.tag_id
WHERE (v.video_id IN (
SELECT gc2.video_id
FROM video_categories gc2
WHERE gc2.genre_id IN(44)
GROUP BY gc2.video_id
HAVING COUNT(gc2.video_id)=1))
AND (v.video_id IN (
SELECT gc2.parent_id
FROM tags_relations gc2
WHERE gc2.tag_id IN(14) AND gc2.department=18
GROUP BY gc2.parent_id
HAVING COUNT(gc2.parent_id)=1))
GROUP BY `v`.`video_id`
ORDER BY `v`.`video_id` DESC
Query takes 0.4s~ to run. It's because of subquery in WHERE statement:
v.video_id IN (
SELECT gc2.parent_id
FROM tags_relations gc2
WHERE gc2.tag_id IN(14) AND gc2.department=18
GROUP BY gc2.parent_id
HAVING COUNT(gc2.parent_id)=1
)
Without it, it runs 0.07s~
Maybe try something with advanced joins? shy
Thanks ;)
In MySQL, never use WHERE in (SELECT ... it is notoriously slow.
Use a join instead:
SELECT `v`.*
, GROUP_CONCAT(DISTINCT(`gg`.genre_id)) AS `genre_ids`
, GROUP_CONCAT(DISTINCT(`gg`.genre_ru)) AS `genres`
, GROUP_CONCAT(DISTINCT(`tg`.tag_id)) AS `tags_ids`
, GROUP_CONCAT(DISTINCT(`tg`.name)) AS `tags`
FROM video AS v
INNER JOIN video_categories AS gc ON gc.video_id = v.video_id
AND gc2.genre_id = '44'
LEFT JOIN video_genres AS gg ON gg.genre_id = gc.genre_id
LEFT JOIN tags_relations AS tr ON tr.department=18 AND tr.parent_id = v.video_id
LEFT JOIN tags AS tg ON tg.tag_id = tr.tag_id
INNER JOIN tags_relations tr2 ON (tr2.parent_id = v.video_id
AND tr2.tag_id = 14 AND tr2.department=18
GROUP BY `v`.`video_id`
ORDER BY `v`.`video_id` DESC
SELECT `v`.*
, GROUP_CONCAT(DISTINCT(`gg`.genre_id)) AS `genre_ids`
, GROUP_CONCAT(DISTINCT(`gg`.genre_ru)) AS `genres`
, GROUP_CONCAT(DISTINCT(`tg`.tag_id)) AS `tags_ids`
, GROUP_CONCAT(DISTINCT(`tg`.name)) AS `tags`
FROM `video` AS `v`
LEFT JOIN `video_categories` AS `gc` ON gc.video_id = v.video_id
LEFT JOIN `video_genres` AS `gg` ON gg.genre_id = gc.genre_id
LEFT JOIN `tags_relations` AS `tr` ON tr.department=18 AND tr.parent_id = v.video_id
LEFT JOIN `tags` AS `tg` ON tg.tag_id = tr.tag_id
JOIN (
SELECT gc2.video_id
FROM video_categories gc2
WHERE gc2.genre_id IN(44)
GROUP BY gc2.video_id
HAVING COUNT(gc2.video_id)=1
) vc ON v.video_id = vc.video_id
JOIN (
SELECT gc2.parent_id
FROM tags_relations gc2
WHERE gc2.tag_id IN(14) AND gc2.department=18
GROUP BY gc2.parent_id
HAVING COUNT(gc2.parent_id)=1
) tr ON v.video_id = tr.parent_id
GROUP BY `v`.`video_id`
ORDER BY `v`.`video_id` DESC
Edit:
I took a closer look at your query and think it can be reduced to the following:
SELECT `v1`.*
, GROUP_CONCAT(DISTINCT(`gg`.genre_id)) AS `genre_ids`
, GROUP_CONCAT(DISTINCT(`gg`.genre_ru)) AS `genres`
, GROUP_CONCAT(DISTINCT(`tg`.tag_id)) AS `tags_ids`
, GROUP_CONCAT(DISTINCT(`tg`.name)) AS `tags`
FROM (
SELECT v.*
FROM `video` AS `v`
LEFT JOIN `video_categories` AS `gc` ON gc.video_id = v.video_id
LEFT JOIN `tags_relations` AS `tr` ON tr.parent_id = v.video_id
WHERE gc.genre_id IN(44)
AND tr.tag_id IN(14)
AND tr.department=18
GROUP BY `v`.`video_id`
HAVING COUNT(*) = 1
) v1
LEFT JOIN `video_genres` AS `gg` ON gg.genre_id = gc.genre_id
LEFT JOIN `tags` AS `tg` ON tg.tag_id = tr.tag_id
GROUP BY v1.video_id
ORDER BY v1.video_id DESC