I have three tables
Let's a demo_organization ;
+--------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| org_name | varchar(100) | NO | | NULL | |
| org_type | varchar(100) | NO | | NULL | |
| abn_acn_no | varchar(100) | NO | | NULL | |
| org_url | varchar(120) | NO | | NULL | |
| notes | longtext | NO | | NULL | |
| city | varchar(100) | YES | | NULL | |
Second one is demo_user
mysql> desc demo_user ;
+--------------------+----------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+----------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| user_name | varchar(100) | NO | | NULL | |
| first_name | varchar(100) | NO | | NULL | |
| middle_name | varchar(100) | NO | | NULL | |
| last_name | varchar(100) | NO | | NULL | |
| image | varchar(10000) | YES | | NULL | |
| password | varchar(80) | NO | | NULL | |
| role | varchar(20) | NO | | NULL | |
| org_name_id | int(11) | NO | MUL | NULL | |
| timezone_id | int(11) | NO | MUL | NULL | |
And third one is the demo_meeting;look like
mysql> desc demo_meeting ;
+--------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(200) | NO | | NULL | |
| meetingID | varchar(50) | NO | | NULL | |
| venue_id | int(11) | YES | MUL | NULL | |
| status | int(11) | YES | | NULL | |
| recurring_time | varchar(50) | NO | | NULL | |
| attendee_passwd | varchar(100) | NO | | NULL | |
| moderator_passwd | varchar(100) | NO | | NULL | |
| date_created | datetime | NO | | NULL | |
| start_time | varchar(100) | NO | | NULL | |
| end_time | varchar(100) | NO | | NULL | |
| meeting_duration | varchar(100) | NO | | NULL | |
| meeting_datetime | datetime | YES | | NULL | |
| timezone | varchar(50) | NO | | NULL | |
| reminder | tinyint(1) | NO | | NULL | |
| duration | varchar(20) | NO | | NULL | |
| created_by_id | int(11) | NO | MUL | NULL | |
In third table created_by_id refers to A user of demo_user table(Foreign key)
And org_name_id(demo_user table ) refers to the demo_organization (Foreign key to demo_organization table )
Updated
mysql> desc demo_meetingroom;
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(100) | NO | | NULL | |
| type | varchar(200) | NO | | NULL | |
| expired_on | varchar(100) | NO | | NULL | |
| user_id | int(11) | YES | MUL | NULL | |
+------------+--------------+------+-----+---------+----------------+
Now i am trying to get all meetings for a particular organization .
I am writing a query like
select meetingID ,type from demo_meeting as dm ,demo_meetingroom as dmr
Where venue_id IS NOT NULL
and dm.name = dmr.name
AND created_by_id IN
(
SELECT id from demo_user WHERE org_name_id IN
(
SELECT id from demo_organization where id =
(SELECT org_name_id from demo_user WHERE user_name = 'God')
)
);
Unfortunately it is returning me Empty set (But there is value )
Please help me out what might i am doing wrong ?
JOIN the three tables instead of these IN's. Something like:
SELECT
dm.meetingID,
dm.type
FROM demo_meeting dm
INNER JOIN demo_user u ON dm.created_by_id = u.id
INNER JOIN demo_organization org ON u.org_name_id = org.id
WHERE u.user_name = 'God'
AND dm.venue_id IS NOT NULL
Much better if you can use JOIN.
SELECT a.meetingID, d.type
FROM demo_meeting a
LEFT JOIN demo_user b
ON a.created_by_id = b.id
LEFT JOIN demo_organization c
ON b.org_name_id = c.id
LEFT JOIN demo_meetingroom d
ON a.name = d.name
WHERE a.venue_id IS NOT NULL AND
b.username = 'GOD'
Related
I have to extract the list of POS(point of service) from pos table, based on location name:
POS
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(100) | NO | | NULL | |
| address | varchar(200) | YES | | NULL | |
| country | varchar(45) | YES | | NULL | |
| location | varchar(100) | YES | | NULL | |
+----------+--------------+------+-----+---------+----------------+
so, it would be something like :
select *
from pos
where location = 'new york';
Now , from the table mission i have to count the number of POS (pos_name), and if this number is greater than a number coming from a subquery, pos register should not be shown.
mission
| id | int(11) | NO | PRI | NULL | auto_increment |
| team_name | varchar(45) | YES | | NULL | |
| team_photo | varchar(255) | YES | | NULL | |
| pos_name | varchar(45) | YES | | NULL | |
| pos_id | int(11) | YES | | NULL | |
| product_category | varchar(45) | YES | | NULL | |
| product_platform | varchar(45) | YES | | NULL | |
| created_by | int(11) | YES | | NULL | |
| judged_by | int(11) | YES | | NULL | |
| selfie_photo | varchar(255) | YES | | NULL | |
| like_score | int(11) | YES | | NULL | |
| star_score | float | YES | | NULL | |
| feedback_recommendation | varchar(2000) | YES | | NULL | |
| created_at | timestamp | YES | | CURRENT_TIMESTAMP | |
| updated_at | timestamp | YES | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| sent_date | timestamp | YES | | NULL | |
| locked | tinyint(1) | YES | | 0 | |
+-------------------------+---------------+------+-----+-------------------+-----------------------------+
so until now i developed following sql query :
SELECT p.id,p.name
FROM missions m join pos p
on m.pos_id = p.id
where p.location = 'new york'
having count(m.pos_name) < (select count(*)
from product_category);
but this part of code
having count(m.pos_name)
should be something like that :
select count(*)
from missions
group by pos_name;
because without group by statement i will recieve a sum of all pos, but i need to check it for a group, not for all of them.
Any suggestion ?
I thing you need the data with group by with condition then try this
SELECT p.id,p.name
FROM missions m join pos p
on m.pos_id = p.id
where p.location = 'new york'
group by m.pos_name
having count(m.pos_name) < (select count(*)
from product_category);
Just add group by m.pos_name it will work.
You can check Here
Im trying to select from a Moodle table the last row of each user in a list.
my query is
SELECT *
FROM mdl_logstore_standard_log
WHERE eventname='\\core\\event\\user_enrolment_created'
AND courseid=34
AND relateduserid IN(120,128)
GROUP BY relateduserid;`
and the table that i use is :
MariaDB [****_*****]> describe mdl_logstore_standard_log;
+-------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+--------------+------+-----+---------+----------------+
| id | bigint(10) | NO | PRI | NULL | auto_increment |
| eventname | varchar(255) | NO | | | |
| component | varchar(100) | NO | | | |
| action | varchar(100) | NO | | | |
| target | varchar(100) | NO | | | |
| objecttable | varchar(50) | YES | | NULL | |
| objectid | bigint(10) | YES | | NULL | |
| crud | varchar(1) | NO | | | |
| edulevel | tinyint(1) | NO | | NULL | |
| contextid | bigint(10) | NO | MUL | NULL | |
| contextlevel | bigint(10) | NO | | NULL | |
| contextinstanceid | bigint(10) | NO | | NULL | |
| userid | bigint(10) | NO | MUL | NULL | |
| courseid | bigint(10) | YES | MUL | NULL | |
| relateduserid | bigint(10) | YES | | NULL | |
| anonymous | tinyint(1) | NO | | 0 | |
| other | longtext | YES | | NULL | |
| timecreated | bigint(10) | NO | MUL | NULL | |
| origin | varchar(10) | YES | | NULL | |
| ip | varchar(45) | YES | | NULL | |
| realuserid | bigint(10) | YES | | NULL | |
+-------------------+--------------+------+-----+---------+----------------+
My Problem with this query is that it give me the first row for every userid in list, and i want the last. i tried order by id desc but nothing changed.
You can try this:
SELECT
L.*
FROM mdl_logstore_standard_log L
INNER JOIN
(
SELECT
relateduserid,
MAX(id) AS max_id
FROM mdl_logstore_standard_log
WHERE eventname='\\core\\event\\user_enrolment_created'
AND courseid=34
AND relateduserid IN(120,128)
GROUP BY relateduserid
)AS t
ON L.id = t.max_id
First getting the maximum auto increment id for those relateduserids then making an inner join between mdl_logstore_standard_log and t table would return your expected result.
Try this but i didnt test it
select * from mdl_logstore_standard_log where eventname='\\core\\event\\user_enrolment_created' and courseid=34 and relateduserid IN(120,128) GROUP BY relateduserid ORDER BY id DESC LIMIT 1;
I have the following 2 tables (student and attendance):
mysql> describe student;
+----------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------------+--------------+------+-----+---------+----------------+
| student_id | int(11) | NO | PRI | NULL | auto_increment |
| student_email | varchar(255) | YES | | NULL | |
| student_phone_number | varchar(255) | YES | | NULL | |
| parent_first_name | varchar(255) | NO | | NULL | |
| parent_last_name | varchar(255) | NO | | NULL | |
| parent_email | varchar(255) | NO | | NULL | |
| parent_phone_number | varchar(255) | NO | | NULL | |
| first_name | varchar(255) | NO | | NULL | |
| last_name | varchar(255) | NO | | NULL | |
| days_absent | int(11) | YES | | NULL | |
| days_tardy | int(11) | YES | | NULL | |
| class_id | int(11) | NO | MUL | NULL | |
+----------------------+--------------+------+-----+---------+----------------+
mysql> describe attendance;
+-----------------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+------------+------+-----+---------+-------+
| student_id | int(11) | NO | PRI | NULL | |
| class_id | int(11) | NO | PRI | NULL | |
| attendance_date | date | NO | PRI | NULL | |
| absent | tinyint(1) | YES | | NULL | |
| tardy | tinyint(1) | YES | | NULL | |
| note | text | YES | | NULL | |
+-----------------+------------+------+-----+---------+-------+
I want to check the attendance and email of all the children who are absent or tardy for the day. Is there a SQL statement I can use that can, for example, select the students from attendance with an absent/tardy value = 1, then using that student_id specified in the attendance table, pull all the student info from the student table where attendance.student_id = student.student_id?
just try exists
select student_email,student_phone_number from student std
where exists(
select 1 from attendance atd where std.student_id = atd.student_id
and (atd.absent =1 or atd.tardy =1)
)
just make sure you select all the info from student table and exists all the filter in attendance talbe. the condition is student_id.
Also if you need info from attendance talbe, then use join.
I've got the following tables:
submissions:
+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| title | varchar(255) | NO | MUL | NULL | |
| slug | varchar(255) | NO | | NULL | |
| description | mediumtext | NO | | NULL | |
| user_id | int(11) | NO | MUL | NULL | |
| created | datetime | NO | | NULL | |
| type | enum('tip','request') | NO | | NULL | |
| thumbnail | varchar(36) | YES | | NULL | |
| removed | tinyint(1) unsigned | NO | | 0 | |
| keywords | varchar(255) | NO | | NULL | |
| ip | int(10) unsigned | NO | | NULL | |
+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------+-----+---------+----------------+
users:
+----------------+------------------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+------------------------+------+-----+-------------------+-----------------------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| email | varchar(128) | NO | MUL | NULL | |
| hash | varchar(64) | NO | | NULL | |
| salt | varchar(32) | NO | | NULL | |
| username | varchar(23) | NO | | NULL | |
| name | varchar(32) | NO | | NULL | |
| about | varchar(255) | NO | | NULL | |
| created | datetime | NO | | NULL | |
| last_login | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| created_ip | int(10) unsigned | NO | | NULL | |
| last_login_ip | int(10) unsigned | NO | | NULL | |
| remember_me | tinyint(3) unsigned | NO | | 0 | |
| photo | varchar(36) | NO | | NULL | |
| confirmed | tinyint(1) unsigned | NO | | 0 | |
| confirm_code | varchar(64) | NO | | NULL | |
| public_profile | tinyint(1) | NO | | 1 | |
+----------------+------------------------+------+-----+-------------------+-----------------------------+
submissions_comments:
+---------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| user_id | int(10) unsigned | NO | MUL | NULL | |
| submission_id | int(11) | NO | MUL | NULL | |
| comment | text | NO | | NULL | |
| parent_id | int(10) unsigned | YES | MUL | NULL | |
| created | datetime | NO | MUL | NULL | |
| created_ip | int(11) | NO | | NULL | |
| helpful_count | int(11) | NO | MUL | NULL | |
| deleted | tinyint(4) | NO | MUL | 0 | |
+---------------+------------------+------+-----+---------+----------------+
And finally my query which returns the count of the submissions (tips and requests), and comments along with all info about the user:
SELECT a.*, sc.user_id,
COALESCE(SUM(CASE WHEN b.type = "tip" THEN 1 ELSE 0 END),0) AS "tipsCount",
COALESCE(SUM(CASE WHEN b.type = "request" THEN 1 ELSE 0 END),0) AS "requestsCount", COALESCE(COUNT(DISTINCT sc.id),0) as "commentsCount"
FROM users as a
LEFT JOIN submissions as b ON a.id = b.user_id
LEFT JOIN submissions_comments as sc
ON a.id = sc.user_id WHERE a.username = ?
AND b.removed = 0
GROUP BY a.id, sc.user_id
LIMIT 1;
And this query works if the user has submitted a tip or request, but otherwise returns NULL. Am I doing a wrong group by or something?
EDIT:
sqlfiddle: http://sqlfiddle.com/#!2/6c56a
I am still not sure what you need so I give you this query which returns Tips, Requests and Comments for a specific user:
SELECT
users.id,
SUM(CASE WHEN submissions.type = "tip" then 1 else 0 END) as tips,
SUM(CASE WHEN submissions.type = "request" then 1 else 0 END) as requests,
(select count(*)
from submissions_comments
where submissions_comments.user_id = users.id) as comments
FROM
users
LEFT JOIN
submissions ON submissions.user_id = users.id
AND submissions.removed = 0
WHERE
users.username = 'amc123'
group by
users.id
SQLFiddle example
I have a table with the following schema:
people_stages
id | person_id | stage_id | created
1 | 1 | 1 | 2013-09-01 00:00:00
2 | 1 | 2 | 2013-09-02 00:00:00
3 | 1 | 3 | 2013-09-03 00:00:00
I have created the following query to select the most recent stage grouped by person:
SELECT *
FROM people Person
LEFT JOIN people_stages PersonStage ON PersonStage.person_id = Person.id
WHERE PersonStage.created = (SELECT MAX(people_stages.created) FROM people_stages GROUP BY person_id HAVING person_id = PersonStage.person_id);
It works fine, however, if I try to ORDER BY a field in the Person table:
SELECT *
FROM people Person
LEFT JOIN people_stages PersonStage ON PersonStage.person_id = Person.id
WHERE PersonStage.created = (SELECT MAX(people_stages.created) FROM people_stages GROUP BY person_id HAVING person_id = PersonStage.person_id)
ORDER BY Person.last_name;
It returns 0 results.
Could anyone provide some insight, please?
Thanks!
EDIT: Structure of people
+----------------------------+--------------------------------------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------------------+--------------------------------------------------------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| internal_id | varchar(50) | NO | MUL | NULL | |
| public_id | varchar(30) | NO | | NULL | |
| counselor_id | bigint(20) | NO | | NULL | |
| term_id | int(11) | NO | MUL | NULL | |
| program_id | int(11) | NO | | NULL | |
| person_type_id | int(11) | NO | MUL | NULL | |
| first_name | varchar(100) | NO | | NULL | |
| middle_name | varchar(100) | NO | | NULL | |
| last_name | varchar(100) | NO | | NULL | |
| photo_url | varchar(255) | NO | | NULL | |
| gender | enum('m','f','u') | NO | | NULL | |
| date_of_birth | date | NO | | NULL | |
| address | varchar(255) | NO | | NULL | |
| address_apt | varchar(100) | NO | | NULL | |
| address_city | varchar(100) | NO | | NULL | |
| address_state | varchar(100) | NO | | NULL | |
| address_state_intl | varchar(255) | NO | | NULL | |
| address_zip | varchar(25) | NO | | NULL | |
| address_country | varchar(100) | NO | | NULL | |
| address_verified | tinyint(1) | NO | | NULL | |
| address_latitude | varchar(100) | NO | | NULL | |
| address_longitude | varchar(100) | NO | | NULL | |
| address_position | point | NO | MUL | NULL | |
| address_distance | smallint(6) | NO | | NULL | |
| social_facebook | mediumtext | NO | | NULL | |
| social_twitter | varchar(255) | NO | | NULL | |
| social_instagram | varchar(255) | NO | | NULL | |
| phone_cell | varchar(25) | NO | | NULL | |
| phone_cell_clean | varchar(25) | YES | | NULL | |
| phone_work | varchar(25) | NO | | NULL | |
| phone_work_clean | varchar(25) | NO | | NULL | |
| permission_to_text | tinyint(1) | NO | | NULL | |
| permission_to_text_confirm | tinyint(1) | NO | | NULL | |
| phone_home | varchar(25) | NO | | NULL | |
| phone_home_clean | varchar(25) | YES | | NULL | |
| email_address | varchar(255) | NO | | NULL | |
| permission_to_email | tinyint(1) | NO | | NULL | |
| preferred_contact | enum('phone_home','phone_cell','text_cell','email','postal') | NO | | NULL | |
| parent_first_name | varchar(100) | NO | | NULL | |
| parent_last_name | varchar(100) | NO | | NULL | |
| parent_email | varchar(255) | NO | | NULL | |
| hs_name | varchar(255) | NO | | NULL | |
| hs_homeschooled | tinyint(1) | NO | | NULL | |
| hs_ceeb_id | varchar(100) | NO | | NULL | |
| hs_grad_year | varchar(4) | NO | | NULL | |
| coll_name | varchar(255) | NO | | NULL | |
| coll_ceeb_id | varchar(100) | NO | | NULL | |
| coll_major | varchar(255) | NO | | NULL | |
| coll_year | varchar(20) | NO | | NULL | |
| counselor_read | tinyint(1) | NO | | NULL | |
| source | varchar(100) | NO | | NULL | |
| entry_method | varchar(100) | NO | | NULL | |
| erp_processed | tinyint(1) | NO | | NULL | |
| created | datetime | NO | | NULL | |
| modified | datetime | NO | | NULL | |
+----------------------------+--------------------------------------------------------------+------+-----+---------+----------------+
This appears to be a bug in MySQL, about which I have filed a report. I have narrowed it to the following test case, which one would expect to return a single record (but it does not):
CREATE TABLE t (x INT NULL); -- table with nullable column
INSERT INTO t VALUES (0); -- but non null data
SELECT a.x -- select our nullable column
FROM t a, (SELECT NULL) b -- joining it with anything at all
WHERE EXISTS ( -- but filter on a subquery
SELECT *
FROM (SELECT NULL) c -- doesn't really matter what
HAVING a.x IS NOT NULL -- provided there is some correlated condition
-- on our nullable column in the HAVING clause
)
ORDER BY RAND() -- then perform a filesort on the outer query
See it on sqlfiddle.
In your case, you can do a number of things to fix this:
Avoid the correlated subquery by rewriting as a join:
SELECT *
FROM people AS p LEFT JOIN (people_stages AS s NATURAL JOIN (
SELECT person_id, MAX(created) created
FROM people_stages
GROUP BY person_id
) t) ON s.person_id = p.id
ORDER BY p.last_name
If you want to keep the correlated subquery (which can generally yield poor performance but is often easier to understand), use WHERE instead of HAVING:
SELECT *
FROM people AS p LEFT JOIN people_stages AS s ON s.person_id = p.id
WHERE s.created = (
SELECT MAX(created)
FROM people_stages
WHERE person_id = s.person_id
)
ORDER BY p.last_name
If you're unable to change the query, you should find that making the people_stages.person_id column non-nullable will get around the problem:
ALTER TABLE people_stages MODIFY person_id BIGINT UNSIGNED NOT NULL
It seems that having an index on that column (which would be required to effect a foreign key constraint) may also help:
ALTER TABLE people_stages ADD FOREIGN KEY (person_id) REFERENCES people (id)
Alternatively one could remove people_stages.person_id from the select list, or adjust the data model/indexing/query strategy to avoid a filesort (may not be practical in this case, but I mention them here for completeness).
Check that you are not running out of space in your server... yes, sounds strange, but a behavior like the one described could be caused by that