I would like to know how can i limit the output by the number of id_offers and not the number of rows. For example
SELECT A.id_offer, T.tags
FROM offer A
INNER JOIN offer_has_tags Z
ON A.id_offer = Z.offer_id_offer
INNER JOIN tags T
ON Z.tags_id_tags = T.id_tags
WHERE state = 0
ORDER BY date
DESC LIMIT 0, 10
output:
id_offer tags
77 xx
76 xx
76 xx
75 xx
75 xx
74 xx
74 xx
73 xx
73 xx
72 xx
Edit: In this case only should be count as 6 offers.
I'm not sure if this is exactly what you want, but I think it is:
SELECT A.id_offer, T.tags
FROM offer A
JOIN offer_has_tags Z
ON A.id_offer = Z.offer_id_offer
JOIN tags T
ON Z.tags_id_tags = T.id_tags
JOIN (
SELECT DISTINCT id_offer
FROM offer
WHERE state = 0
ORDER BY date DESC
LIMIT 10
) L
ON A.id_offer = L.id_offer
or the more simple:
SELECT A.id_offer, T.tags
FROM
( SELECT *
FROM offer
WHERE state = 0
ORDER BY date DESC
LIMIT 10
) A
JOIN offer_has_tags Z
ON A.id_offer = Z.offer_id_offer
JOIN tags T
ON Z.tags_id_tags = T.id_tags
you can try this:
SELECT A.id_offer, T.tags
FROM offer A
INNER JOIN offer_has_tags Z
ON A.id_offer = Z.offer_id_offer
INNER JOIN tags T
ON Z.tags_id_tags = T.id_tags
WHERE (state = 0) AND
(A.id_offer >= 72 AND A.id_offer <= 77)
ORDER BY date
You simply have to use DISTINCT:
SELECT DISTINCT A.id_offer, T.tags
FROM offer A
INNER JOIN offer_has_tags Z
ON A.id_offer = Z.offer_id_offer
INNER JOIN tags T
ON Z.tags_id_tags = T.id_tags
WHERE state = 0
ORDER BY date
DESC LIMIT 0, 10
Related
This query is taking over 4 seconds to run killing the performance on the page.
The query is doing a sum of points getting the max point by day for a product for a particular month. The purpose is to display a ranking for a given month ordered by the sum of points.
SELECT eriginal_asin, DATE_FORMAT(date_time,'%m/%d/%Y %h:%i:%s') as date_time, SUM(maxpoints) as points, `o1`.`value` as value,
`o2`.`value` as value1, `o3`.`value` as value2, `o4`.`value` as value3, `o5`.`value` as value4, `o6`.`value` as value5,
`o7`.`value` as value6, `o8`.`value` as value7, `o9`.`value` as value8, `o10`.`value` as value9, `o11`.`value` as value10,
`o12`.`value` as value11, `o13`.`value` as value12, `o14`.`value` as value13, `o15`.`value` as value14, `o16`.`value` as value15,
`o17`.`value` as value16, property.id, user.name_surname, user.name_last
from
(SELECT id, eriginal_asin, max(points) as maxpoints, DATE_FORMAT(date_time,'%m/%d/%Y %h:%i:%s') as date_time
from ranking
where date_time >= '2015-09-01'
and date_time <= '2015-09-30 23:59:59'
and points > 0
group by eriginal_asin, region, date(date_time)
)rankmax, property
LEFT JOIN `property_user` ON `property`.`id` = `property_user`.`property_id`
LEFT JOIN `user` ON `property_user`.`user_id` = `user`.`id`
LEFT JOIN `property_value` o1 ON `property`.`id` = `o1`.`property_id` and o1.option_id = 17
LEFT JOIN `property_value` o2 ON `property`.`id` = `o2`.`property_id` and o2.option_id = 10
LEFT JOIN `property_value` o3 ON `property`.`id` = `o3`.`property_id` and o3.option_id = 54
LEFT JOIN `property_value` o4 ON `property`.`id` = `o4`.`property_id` and o4.option_id = 64
LEFT JOIN `property_value` o5 ON `property`.`id` = `o5`.`property_id` and o5.option_id = 65
LEFT JOIN `property_value` o6 ON `property`.`id` = `o6`.`property_id` and o6.option_id = 5
LEFT JOIN `property_value` o7 ON `property`.`id` = `o7`.`property_id` and o7.option_id = 6
LEFT JOIN `property_value` o8 ON `property`.`id` = `o8`.`property_id` and o8.option_id = 10
LEFT JOIN `property_value` o9 ON `property`.`id` = `o9`.`property_id` and o9.option_id = 63
LEFT JOIN `property_value` o10 ON `property`.`id` = `o10`.`property_id` and o10.option_id = 55
LEFT JOIN `property_value` o11 ON `property`.`id` = `o11`.`property_id` and o11.option_id = 56
LEFT JOIN `property_value` o12 ON `property`.`id` = `o12`.`property_id` and o12.option_id = 57
LEFT JOIN `property_value` o13 ON `property`.`id` = `o13`.`property_id` and o13.option_id = 58
LEFT JOIN `property_value` o14 ON `property`.`id` = `o14`.`property_id` and o14.option_id = 59
LEFT JOIN `property_value` o15 ON `property`.`id` = `o15`.`property_id` and o15.option_id = 60
LEFT JOIN `property_value` o16 ON `property`.`id` = `o16`.`property_id` and o16.option_id = 61
LEFT JOIN `property_value` o17 ON `property`.`id` = `o17`.`property_id` and o17.option_id = 62
where property.is_activated = 1
and o1.value = eriginal_asin
GROUP BY DATE(date_time), eriginal_asin
order by points desc
one thing is, you can do it with one LEFT JOIN. I have made a sample (not with all columns) to test if it works better
SELECT eriginal_asin,
DATE_FORMAT(date_time,'%m/%d/%Y %h:%i:%s') AS date_time,
SUM(maxpoints) AS points,
coalesce( IF( o.property_id = 17, `o`.`value`, NULL )) AS value_1,
coalesce(IF (o.property_id = 10, `o`.`value`, NULL )) AS value_
coalesce(IF (o.property_id = 54, `o`.`value`, NULL )) AS value_3,
coalesce(IF (o.property_id = 64, `o`.`value`, NULL )) AS value_4,
property.id,
user.name_surname,
user.name_last
FROM
(SELECT id,
eriginal_asin,
max(points) AS maxpoints,
DATE_FORMAT(date_time,'%m/%d/%Y %h:%i:%s') AS date_time
FROM ranking
WHERE date_time >= '2015-09-01'
AND date_time <= '2015-09-30 23:59:59'
AND points > 0
GROUP BY eriginal_asin,
region,
date(date_time) )rankmax,
property
LEFT JOIN `property_user` ON `property`.`id` = `property_user`.`property_id`
LEFT JOIN `user` ON `property_user`.`user_id` = `user`.`id`
LEFT JOIN `property_value` o ON `property`.`id` = `o`.`property_id`
WHERE property.is_activated = 1
AND o1.value = eriginal_asin
GROUP BY o.property_id,
DATE(date_time),
eriginal_asin
ORDER BY points DESC;
A few things... Can you please provide some sample data of your "Property_Value" table records... what are the "values". Ranking.ID... Is that the ID associated to the property? You have no join condition to that and THAT may be causing a Cartesian result.
Does the Ranking table have a "Property_ID" column to join against. Do you have index on your property_value table on ( value, id, option_id )... A combination/multi-field index would significantly help too.
Also, it is unclear exactly how / where the property ID is based on the RankMax table -- or does the property table have the "eriginal_asin" column (doubt it).
Existing table structures and some sample data (space formatting of data instead of tabs preferred) would help myself and/or others to helping you out.
EXAMPLE ONLY OF DATA (you can copy/paste in your original question and adjust content as needed), but your join criteria really is missing somewhere.
Property Table
ID Is_Activiated OtherDescript
1 1 Test Sample
2 0 Another Property
3 1 last
User Table
ID UserName
PropertyUser Table
ID Property_ID
1 3
2 1
3 2
Property_value table
ID Property_ID Option_ID Value
1 3 17 blah
1 3 10 another
1 3 54 blah 2
I have three tables: tblFuel, tblDoXang, tblDrivingTime2. Now I want to show the fuelLevel field in tblFuel that satisfy some condition in tblDrivingTime2 and if in specific of time(base on timestamp in tblFuel) if I check there are adding fuel action in tblDoXang, I have to insert it(nhienLieu field in tblDoXang) to report that show fuelLevel above. The goal is likely:
tblFuel:
timestamp fuelLevel
123456 10
123467 8
123478 50
123489 20
tblDrivingTime2:
stopTime
123456
123478
123489
this will print:
10
50
20
and now we check if
tblDoXang
thoiGian nhienLieu
123457 15
123466 10
it will insert to result above and finally, the result will be:
10
15
10
50
20
I have written two separated queries to do these tasks:
SELECT distinct from_unixtime(F.timestamp), F.fuelLevel FROM gtse.tblFuel F
INNER JOIN gtse.tblDrivingTime2 D
ON D.accountID = F.accountID and D.deviceID = F.deviceID
where (from_unixtime(F.timestamp) between '2014-10-10 10:52:02' and '2014-10-30 10:52:02')
and F.accountID = 'vinhnghia'
and F.deviceID = '14C-00263'
and (D.reportType = '2' or D.reportType = '3')
and F.timestamp = D.stopTime
order by F.timestamp asc;
this will print the result in the first time(10,50 and 20) and this:
SELECT distinct from_unixtime(D.thoiGian), D.nhienLieu
FROM gtse.tblDoXang D
inner join gtse.tblFuel F
on D.accountID = F.accountID and D.deviceID = F.deviceID
where D.accountID = 'vinhnghia' and D.deviceID = '14C-00263'
and D.thoiGian <= F.timestamp
order by D.thoiGian asc;
will show the value(15,10). And my question is how to join two queries to show the final result?:
10
15
10
50
20
Maybe you could try with the UNION clause:
(
SELECT distinct
from_unixtime(F.timestamp) As col_1,
F.fuelLevel as col_2
FROM
gtse.tblFuel F
INNER JOIN gtse.tblDrivingTime2 D
ON D.accountID = F.accountID
and D.deviceID = F.deviceID
where
(from_unixtime(F.timestamp) between '2014-10-10 10:52:02' and '2014-10-30 10:52:02')
and F.accountID = 'vinhnghia'
and F.deviceID = '14C-00263'
and (D.reportType = '2' or D.reportType = '3')
and F.timestamp = D.stopTime
order by
F.timestamp asc
)
UNION
(
SELECT distinct
from_unixtime(D.thoiGian) as col_1,
D.nhienLieu as col_2
FROM
gtse.tblDoXang D
inner join gtse.tblFuel F
on D.accountID = F.accountID
and D.deviceID = F.deviceID
where
D.accountID = 'vinhnghia'
and D.deviceID = '14C-00263'
and D.thoiGian <= F.timestamp
order by
D.thoiGian asc;
)
I hope I understood well and this could help.
I have two queries giving two sets of result, i want to divide one query's result with another.
Here is my first query :
SELECT COUNT(*)
FROM survey_event_answers a JOIN survey_events e ON a.eventid = e.eventid
WHERE e.event_status = 'Closed' AND
e.survey_date BETWEEN '2013-05-01' AND '2014-01-31' AND
a.response_options IN (10,11) AND a.questionid = 7
GROUP BY MONTH(e.survey_date) DESC;
Here is the result of this query :
279
443
664
743
785
1312
1085
915
231
Here is my another query :
SELECT COUNT(*),e.survey_date
FROM `survey_event_answers` a INNER JOIN survey_events e ON a.eventid = e.eventid
WHERE e.event_status='Closed' AND
e.survey_date BETWEEN '2013-05-01' AND '2014-01-31' AND
a.questionid=7
GROUP BY MONTH(e.survey_date) DESC
Here is the query result :
351
539
826
926
984
1654
1378
1165
844
I want that first row of first result set should divide by first row of second row set.
Please help me out how can i do this.
Thanks
is this what are you looking for?
SELECT rd1.r1/rd2.r2 `result`
FROM (
SELECT COUNT(*) r1,MONTH(e.survey_date) d1
FROM `survey_event_answers` a
INNER JOIN survey_events e
ON (a.eventid = e.eventid)
WHERE e.event_status='Closed' AND e.survey_date BETWEEN '2013-05-01' AND '2014-01-31'
AND a.response_options IN (10,11) AND a.questionid=7
GROUP BY MONTH(e.survey_date) DESC ) rd1
JOIN (
SELECT COUNT(*) r2, MONTH(e.survey_date) d2
FROM `survey_event_answers` a
INNER JOIN survey_events e
ON (a.eventid = e.eventid)
WHERE e.event_status='Closed' AND e.survey_date BETWEEN '2013-05-01' AND '2014-01-31'
AND a.questionid=7
GROUP BY MONTH(e.survey_date) DESC ) rd2
ON rd1.d1=rd2.d2
You could do:
SELECT SUM(IF(a.response_options IN (10,11), 1, 0))/COUNT(*)
FROM survey_event_answers a
JOIN survey_events e
ON a.eventid = e.eventid
WHERE e.event_status = 'Closed'
AND e.survey_date BETWEEN '2013-05-01' AND '2014-01-31'
AND a.questionid = 7
GROUP BY MONTH(e.survey_date) DESC;
This may not be fast (but it is faster than doing the query twice and joining the results), but probably do what you want (ratio of answers 10 or 11). You can add the MONTH(e.survey_date) as a second column.
I need help about generating query for multiple column.
part of my tbl_advert_specific_fields_values table look like:
id advert_id field_name field_value
1 654 t1_sqft 50
2 655 t1_yearbuilt 1999
3 1521 t2_doorcount 5
4 656 t1_yearbuilt 2001
5 656 t1_sqft 29
6 654 t1_yearbuilt 2004
SELECT p.*, p.id AS id, p.title AS title, usr.id as advert_user_id,
p.street_num, p.street,c.icon AS cat_icon,c.title AS cat_title,c.title AS cat_title,
p.description as description,
countries.title as country_name,
states.title as state_name,
date_FORMAT(p.created, '%Y-%m-%d') as fcreated
FROM tbl AS p
LEFT JOIN tbl_advertmid AS pm ON pm.advert_id = p.id
INNER JOIN tbl_usermid AS am ON am.advert_id = p.id
LEFT JOIN tbl_users AS usr ON usr.id = am.user_id
INNER JOIN tbl_categories AS c ON c.id = pm.cat_id
INNER JOIN tbl_advert_specific_fields_values AS asfv ON asfv.advert_id = p.id
LEFT JOIN tbl_countries AS countries ON countries.id = p.country
LEFT JOIN tbl_states AS states ON states.id = p.locstate
WHERE p.published = 1 AND p.approved = 1 AND c.published = 1
AND (asfv.field_name = 't1_yearbuilt'
AND CONVERT(asfv.field_value,SIGNED) <= 2004 )
AND (asfv.field_name = 't1_sqft'
AND CONVERT(asfv.field_value,SIGNED) <= 50)
AND p.price <= 10174945 AND (p.advert_type_id = 1)
AND (c.id = 43 OR c.parent = 43)
GROUP BY p.id
ORDER BY p.price DESC
ok, the problem is in this asfv query part that are generated dynamically. It belong to objects which represent adverts by its specific fields. asfv is actually advert_specific_fields_values table (table name say all about it).
Without part:
AND (asfv.field_name = 't1_yearbuilt'
AND CONVERT(asfv.field_value,SIGNED) <= 2004 )
AND (asfv.field_name = 't1_sqft'
AND CONVERT(asfv.field_value,SIGNED) <= 50)
query return all adverts that belong on advert_type_id and price of them are less than 10.174.945,00 €.
All what I need is query update that return only adverts, for example t1_yearbuilt less than 2005 and t1_sqft less than 51 (advert_id => 654,656).
I also need query for values between for example t1_sqft >=30 AND t1_sqft <=50 (advert_id => 654).
Can anybody know how, update this query?
TNX
I have a set of articles. Some of these articles have been assigned x number of tags.
I want to select all articles in the format specified in the SELECT, and if the article also has any number of tags assigned, put them into a single GROUP_CONCAT field.
The SQL below does everything I need, except it only retrieves articles that have at least one tag.
How can I make it so that the tagging requirement is optional?
SELECT d.entry_id AS entry_id
, d.field_id_40 AS body
, t.title AS title
, t.url_title AS url_title
, t.entry_date AS entry_date
, GROUP_CONCAT(g.tag_name ORDER BY g.tag_name) AS tag
FROM exp_channel_data d
, exp_category_posts c
, exp_channel_titles t
, exp_tagger_links l
, exp_tagger g
WHERE t.YEAR > '2005'
AND t.site_id = d.site_id
AND d.site_id = 9
AND ( c.cat_id = 95
OR c.cat_id = 93
OR c.cat_id = 64
OR c.cat_id = 24
)
AND d.entry_id = t.entry_id
AND t.entry_id = c.entry_id
AND t.STATUS = 'open'
AND l.tag_id = g.tag_id
AND d.entry_id = l.entry_id
GROUP BY d.entry_id
Switching your JOINS to use the JOIN syntax, this should provide you with your answer.
SELECT d.entry_id AS entry_id
, d.field_id_40 AS body
, t.title AS title
, t.url_title AS url_title
, t.entry_date AS entry_date
, GROUP_CONCAT(g.tag_name ORDER BY g.tag_name) AS tag
FROM exp_channel_data AS d
INNER JOIN exp_channel_titles AS t ON d.site_id = t.site_id
AND d.entry_id = t.entry_id
INNER JOIN exp_category_posts AS c ON t.entry_id = c.entry_id
LEFT OUTER JOIN exp_tagger_links AS l ON d.entry_id = l.entry_id
LEFT OUTER JOIN exp_tagger AS g ON l.tag_id = g.tag_id
WHERE t.YEAR > '2005'
AND d.site_id = 9
AND c.cat_id IN (95, 93, 64, 24)
AND t.STATUS = 'open'
GROUP BY d.entry_id
You may also want to look at A visual explanation of SQL joins.