I am going to run a query which gives latest arrears when provided with admission_code, but there is some logical error:
SELECT *
FROM fees_invoice_information AS fii
WHERE fii.admission_code = 12111
This SQL returns:
enter image description here
While when I want to get latest record from following query
SELECT
MAX(fii.id),fii.*,
sep.registration_code,
sep.admission_code,
fii.arrears,
sep.is_enabled
FROM
fees_invoice_information AS fii
JOIN
std_education_profile AS sep ON fii.admission_code = sep.admission_code
WHERE
fii.`admission_code` = 12111
I get:
enter image description here
In which "arrears" column is not '0'
Move the MAX criteria to a subquery in the WHERE clause:
SELECT fii.*,
sep.registration_code,
sep.admission_code,
sep.is_enabled
FROM fees_invoice_information AS fii
INNER JOIN std_education_profile AS sep
ON fii.admission_code = sep.admission_code
WHERE fii.admission_code = 12111 AND
fii.id = (SELECT MAX(id) FROM fees_invoice_information)
Or you could use a LIMIT 1 trick:
SELECT fii.*,
sep.registration_code,
sep.admission_code,
sep.is_enabled
FROM fees_invoice_information AS fii
INNER JOIN std_education_profile AS sep
ON fii.admission_code = sep.admission_code
WHERE fii.admission_code = 12111
ORDER BY fii.id DESC
LIMIT 1
Note: This assumes that it makes logical sense to return only a single record based on the max ID. If the join isn't one to one then you might want to return a group of records, or an aggregate of a group of records.
Related
I'm trying to substitute my join SQL code to a different code without any of JOIN statements for faster data retrieval. However, i'm getting the error below.
#1242 - Subquery returns more than 1 row
What i would like to do, get all rows from one table 'tbl_my_itemlist' and JOIN to other more tables, tbl_register and tbl_register without using JOIN statements.
The Code using JOIN statement (works fine).
SELECT
tbl_screenshots.screenshot_image_url,
mit.my_itemlist_id,
mit.item_name,
mit.item_initial_cost,
mit.item_offer_cost,
mit.offer_date_from,
mit.offer_date_to
FROM
(
SELECT
my_itemlist_id
FROM
tbl_my_itemlist
WHERE
offer_date_from >='2020-10-20' AND offer_date_to <= '2020-10-30' AND
item_deleted_status = 'active'
) mlist
JOIN tbl_my_itemlist mit ON
mit.my_itemlist_id = mlist.my_itemlist_id
RIGHT JOIN tbl_screenshots ON mit.my_itemlist_id =
tbl_screenshots.my_itemlist_id
RIGHT JOIN tbl_register ON tbl_register.register_id = mit.register_id
GROUP BY
mit.my_itemlist_id
ORDER BY mit.offer_date_to ASC LIMIT 2
The code i'm substituting the JOIN statement code with.
SELECT
mit.my_itemlist_id,
mit.item_name,
mit.item_initial_cost,
mit.item_offer_cost,
mit.offer_date_from,
mit.offer_date_to,
(
SELECT
reg.business_name
FROM
tbl_register reg
WHERE
reg.register_id = mit.register_id
) reg_sql,
(
SELECT
sshots.screenshot_image_url
FROM
tbl_screenshots sshots
WHERE
sshots.my_itemlist_id = mit.my_itemlist_id
) sshots_sq
FROM
tbl_my_itemlist mit
WHERE
mit.offer_date_from >= '2020-10-20' AND mit.offer_date_to <= '2020-10-30' AND mit.item_deleted_status = 'active'
GROUP BY
mit.my_itemlist_id
ORDER BY
mit.offer_date_to ASC
LIMIT 2
I'm trying to build an SQL query that can retrieve data from million records within very short period of time as compared to using the JOIN statement.
I want to use criteria->group in yii query but it gives error like
CDbCommand failed to execute the SQL statement: SQLSTATE[42S21]
currently i use is:
$criteria->group = 'reg.user_first_name';
$criteria->order = 't.inout_time';
when i use only order by then it works proper like:
SELECT `t`.`attendant_id`, `t`.`user_id` FROM `attendance_master` `t`
LEFT JOIN registration_master reg on reg.ai_sync_id = t.user_id
WHERE (((t.well_master_id=:ycp0) AND (t.status=:ycp1)) AND (t.user_type_id=:ycp2)) AND (t.inout_time LIKE :time)
ORDER BY t.inout_time LIMIT 10.
Bound with :ycp0='1429082167', :ycp1='in', :ycp2='2', :time='2015-05-06%'
but when i add group by condition then error occurs like:
1060 Duplicate column name 'ai_sync_id'. The SQL statement executed was:
SELECT COUNT(*) FROM (SELECT * FROM `attendance_master` `t`
LEFT JOIN registration_master reg on reg.ai_sync_id = t.user_id
WHERE (((t.well_master_id=:ycp0) AND (t.status=:ycp1)) AND (t.user_type_id=:ycp2)) AND (t.inout_time LIKE :time)
GROUP BY reg.user_first_name) sq.
Bound with :ycp0='1429082167', :ycp1='in', :ycp2='2', :time='2015-05-06%'
i know this is a small issue but i cant find as i am new in yii.
You can't group by reg.user_first_name when do SELECT t.attendant_id, t.user_id FROM ... group field must be in result set.
So try just:
SELECT `t`.`attendant_id`, `t`.`user_id`, reg.user_first_name FROM
and if you do GROUP BY you should use any aggregate function (SUM, COUNT, MAX ...)usually.
in below query it returns 12 record while query in from clause (as t) returns 18 record, can anyone help what is the issue in this query?
SELECT count(abc.id) as total_this_month,t.*
FROM email_details abc
JOIN
(SELECT count(email_details.id) as total_emails,MAX(`email_details`.email_date) as email_date1, `email_details`.* FROM (`cld_users` join email_details on email_details.fk_user_id = cld_users.id) GROUP BY `email_details`.`email_title` ORDER BY `email_details`.`email_date` DESC) as t
ON abc.email_title = t.email_title
where (MONTH(abc.email_date)=MONTH(NOW()) AND YEAR(abc.email_date)=YEAR(NOW()))
group by t.email_title
ORDER BY t.`email_date` DESC
In your query, you specify
where (MONTH(abc.email_date)=MONTH(NOW()) AND YEAR(abc.email_date)=YEAR(NOW()))
But in the subquery (the one returning 18 results), you have 6 emails with a month that is not december 2014. There's no way that those emails can be returned by a query that explicitly excludes them.
You want those emails as well so you get 18 results ? Remove the WHERE clause excluding them:
SELECT Count(abc.id) AS total_this_month,
t.*
FROM email_details abc
JOIN (SELECT Count(email_details.id) AS total_emails,
Max(`email_details`.email_date) AS email_date1,
`email_details`.*
FROM (`cld_users`
JOIN email_details
ON email_details.fk_user_id = cld_users.id)
GROUP BY `email_details`.`email_title`
ORDER BY `email_details`.`email_date` DESC) AS t
ON abc.email_title = t.email_title
GROUP BY t.email_title
ORDER BY t.`email_date` DESC
Starting from there, if you want to count the emails from the current month, simply replace:
SELECT Count(abc.id) AS total_this_month,
with
SELECT SUM(CASE WHEN MONTH(abc.email_date)=MONTH(NOW()) AND YEAR(abc.email_date)=YEAR(NOW()) THEN 1 ELSE 0 END) AS total_this_month,
I have two mysql tables with content one is called petitions
{"success":1,"petitions":[{"id":"6","name":"should he go","timestamp":"2013-10-26 03:02:44"},{"id":"3","name":"Olara Otunu should get married","timestamp":"2013-10-24 14:33:53"},{"id":"4","name":"Teachers deserve 30 not 20 salary rise","timestamp":"2013-10-24 14:33:53"},{"id":"5","name":"Prostitution should be banned","timestamp":"2013-10-24 14:33:53"},{"id":"1","name":"Has Jennifer Musisi done great work for Kampala","timestamp":"2013-10-24 14:32:58"},{"id":"2","name":"Do lecturers deserve 100% salary increase","timestamp":"2013-10-24 14:32:58"}]}
and the other table is called petition_response
{"success":1,"petition_response":[{"id":"2","petitionID":"2","yes":"0","no":"1","memberID":"14","timestamp":"2013-11-02 08:36:20"},{"id":"1","petitionID":"1","yes":"1","no":"0","memberID":"14","timestamp":"2013-11-01 21:26:02"}]}
I need to select * petitions which have no response in the petition_response. But if they have any response in the petition_response table then the memberID should not be equal to 14
I have tried this code below but its not working
$result = mysql_query("select * from petition_response where memberID='14' order by timestamp DESC", $db->connect());
while($row = mysql_fetch_assoc($result)){
$id = $row['id'];
$result2 = mysql_query("select * from petitions where id != '$id' order by timestamp DESC", $db->connect());
}
return $result2;
You're looking to effect an anti-join, for which there are three possibilities in MySQL:
Using NOT IN:
SELECT *
FROM petitions
WHERE id NOT IN (
SELECT petitionID
FROM petition_response
WHERE memberID = 14
)
Using NOT EXISTS:
SELECT *
FROM petitions p
WHERE NOT EXISTS (
SELECT *
FROM petition_response r
WHERE r.petitionID = p.id
AND r.memberID = 14
LIMIT 1
)
Using an OUTER JOIN:
SELECT p.*
FROM petitions p
LEFT OUTER JOIN petition_response r
ON r.petitionID = p.id AND r.memberID = 14
WHERE r.petitionID IS NULL
See them on sqlfiddle.
According to #Quassnoi's analysis:
Summary
MySQL can optimize all three methods to do a sort of NESTED LOOPS ANTI JOIN.
It will take each value from t_left and look it up in the index on t_right.value. In case of an index hit or an index miss, the corresponding predicate will immediately return FALSE or TRUE, respectively, and the decision to return the row from t_left or not will be made immediately without examining other rows in t_right.
However, these three methods generate three different plans which are executed by three different pieces of code. The code that executes EXISTS predicate is about 30% less efficient than those that execute index_subquery and LEFT JOIN optimized to use Not exists method.
That’s why the best way to search for missing values in MySQL is using a LEFT JOIN / IS NULL or NOT IN rather than NOT EXISTS.
$query = "
SELECT *
FROM petition_response pr
LEFT
JOIN petitions p
ON p.id = pr.id
WHERE pr.memberID = 14
AND p.id IS NULL
ORDER
BY pr.timestamp DESC;
";
How can I merge the following queries together?
To get all the objects of a particular type I use
SELECT ID FROM social_objects
WHERE subgroup='23' ORDER BY time_created DESC LIMIT 0 , 30
I have this search too, for titles
SELECT ID FROM 'social_objects_single'
WHERE 'title' LIKE '%indian%' LIMIT 0 , 30
How can I get only objects of subgroup 23 with certain titles?
How are the two tables related? If they both reference an ID you inner join and use AND to combine conditions:
SELECT Parent.ID, Child.ID
FROM ParentTable
INNER JOIN ChildTable ON ParentTable.ID = ChildTable.ForeignKeyID
WHERE Parent.ID = 23 AND Title LIKE '%indian%'
If your social_objects_single has the same ID as the social_objects table you could do this:
SELECT so.ID FROM social_objects so
INNER JOIN social_objects_single soi ON soi.ID = so.ID
WHERE so.subgroup = 23 AND soi.title LIKE '%indian%'
ORDER BY so.time_created DESC LIMIT 0, 30;
SELECT SO.ID,SOS.ID
FROM social_objects SO ,social_objects_single SOS WHERE SOS.title LIKE '%indian% and SO.subgroup=23 and SOS.id =SO.subgroup_id
you should replace the last condition SOS.id =SO.subgroup_id as your tables are connected