I have two tables and I want to display all records from the first table where the field that joins them is not present in the second table.
$sql = "SELECT d.*,t.id from `donations` d
JOIN `teams` t
ON d.teamid = t.id
WHERE t.id IS NULL";
In other words I want to join donations and teams. But I want to retrieve only the records from donations where the team field is not present in the teams table.
The above displays zero records and is not doing the trick.
Thanks for any suggestions.
SELECT d.*,t.id from `donations` d
LEFT OUTER JOIN `teams` t
ON d.teamid = t.id
WHERE t.id IS NULL
You could use a sub query.
select * from donations
where teamid not in (
select id from teams
)
That should select all donations which has a teamid which is not present in the teams table.
Related
how to perform sql count(*) query on results of another query performing multiple results ?
I've 3 tables :--
user_subscribe table where I've 'user_id' and other columns.
user table where we have 'user_id' & 'country_id' columns where user_id is being linked with user_subscribe table and country_id is being linked with 'country' table.
country table having 'country_id' column.
I need to get total count of user_subscribe based on users (user_id) who belongs to same country.
A Help is highly appreciated as I'm being stuck on this problem from last 7 days.
SELECT COUNT(US.user_id) as country_user_subscribed
FROM user_subscribe as US
LEFT JOIN users as U ON user.id=US.user_id
LEFT JOIN countries as C on C.id=U.country_id
GROUP BY C.country_id
Try This Solution :
SELECT C.CountryName,Count(u.UserId) AS UserCount FROM User_Subscribe AS us
LEFT JOIN User AS u ON us.UserId = u.UserId
LEFT JOIN Country AS c ON u.CountryId = c.CountryId
WHERE c.CountryId = 3
GROUP BY c.CountryName
I have 2 MySQL tables (countries) and (reservations)
I want to list every row from countries and simply indicate whether there is a match on reservations or not.
In each instance:
reservations will have 1 matching rows, or
reservations will have many matching rows, or
reservations will have no matching rows
So all I want from the join is to know whether there is a match to reservations or not. Nothing else.
Here is my query statement:
SELECT country.countryID, reservation.citizen
FROM countries AS country
LEFT JOIN (
SELECT reservationID
FROM reservations
LIMIT 1
) AS reservation ON reservation.citizen = country.countryID
ORDER BY reservation.citizen
It fails with Unknown column 'reservation.citizen' in 'on clause'
CONCLUSION:
JOINs cannot solve the problem.
The issue is in the subselect. Notice you have not included the field citizen inside reservation.
SELECT country.countryID, reservation.citizen
FROM countries AS country
LEFT JOIN (
SELECT reservationID, citizen
FROM reservations
LIMIT 1
) AS reservation ON reservation.citizen = country.countryID
ORDER BY reservation.citizen
By the other hand, why are you doing a subselect? And why the limit? Wouldn't be better to just query the following?
SELECT
country.countryID,
count(reservation.reservationID)
FROM
countries AS country
LEFT JOIN reservations AS reservation
ON country.countryID = reservation.citizen
GROUP BY
country.countryID
HAVING
count(reservation.reservationID) > 0
ORDER BY
reservation.citizen
;
You have an issue with the join, it should be like
LEFT JOIN reservations AS reservation ON reservation.citizen = country.countryID
ORDER BY reservation.citizen
OR
LEFT JOIN (
SELECT *
FROM reservations
LIMIT 1
) AS reservation ON reservation.citizen = country.countryID
ORDER BY reservation.citizen
OR better LEFT OUTER JOIN to get rows not matching join conditions.
LEFT OUTER JOIN reservations AS reservation ON reservation.citizen = country.countryID
ORDER BY reservation.citizen
A misconfigured manual import imported our entire AD into our help desk user database, creating a bunch of extraneous/duplicate accounts. Of course, no backup to restore from.
To facilitate the cleanup, I want to run a query that will find users not currently linked to any current or archived tickets. I have three tables, USER, HD_TICKET, and HD_ARCHIVE_TICKET. I want to compare the ID field in USER to the OWNER_ID and SUBMITTER_ID fields in the other two tables, returning the only the values in USER.ID that do not exist in any of the other four columns.
How can this be accomplished?
Do a left join for each relationship where the right table id is null:
select user.*
from user
left join hd_ticket on user.id = hd_ticket.owner_id
left join hd_ticket as hd_ticket2 on user.id = hd_ticket2.submitter_id
left join hd_archive_ticket on user.id = hd_archive_ticket.owner_id
left join hd_archive_ticket as hd_archive_ticket2 on user.id = hd_archive_ticket2.submitter_id
where hd_ticket.owner_id is null
and hd_ticket2.submitter_id is null
and hd_archive_ticket.owner_id is null
and hd_archive_ticket2.submitter_id is null
How about something like:
SELECT id
FROM user
WHERE id NOT IN
(
SELECT owner_id
FROM hd_ticket
UNION ALL
SELECT submitter_id
FROM hd_ticket
UNION ALL
SELECT owner_id
FROM hd_archive_ticket
UNION ALL
SELECT submitter_id
FROM hd_archive_ticket
)
If I understood you situation I would do this:
SELECT a.id FROM user a, hd_ticket b, hd_archive_ticket c WHERE a.id != b.id AND a.id != c.id
You would want to try something like below. Inner query where I am doing Inner join with other 2 tables, will return only those user id which exist in all 3 tables. Then in your outer query I am just filtering out those ID's returned by inner query; since your goal is to get only those USER ID which is not present in other tables.
select ID
FROM USER
WHERE ID NOT IN
(
select u.ID
from user u
inner join HD_TICKET h on u.ID = h.OWNER_ID
inner join HD_ARCHIVE_TICKET ha on u.ID = ha.SUBMITTER_ID
)
I'm trying to make a SQL query that will search for user id and populate the query with the username.
These are my tables:
Table Names: 'users' and 'schedule'
This is how I want it to look like, where 'schedule' table now shows the username instead of the user's ID
This is the query you are looking for:
SELECT s.REFID, s.jobnum, s.customer, u1.username AS engineer, u2.username AS sales
FROM schedule s, users u1, users u2
WHERE s.engineer=u1.id
AND s.sales=u2.id
You need to reference the users table two separate times, since you are checking in one sub-query for the engineer's username, and then checking in a separate sub-query for the salesperson's username.
Here is a link to an SQLFiddle that shows the result of the query's execution. It matches up with what you were looking for. I hope this helps.
Following Query will give you the expected result:
SELECT
s.refid as refid,
s.jobnum as jobnum,
s.customer as customer,
u_engg.username as engineer,
u_sales.username as sales
FROM
user u_engg join schedule s on u.id = s.engineer join
user u_sale on u_sale.id = s.sales
SELECT s.refid, s.jobnum, s.customer, u.username engineer, u.username sales
FROM schedule s
LEFT OUTER JOIN users u
ON s.engineer = u.id AND s.sales = u.id
It looks like you need to reference the users table two times. One JOIN to get the engineer username, and a second JOIN to get the sales username.
Something like this:
-- return all rows from schedule, and lookup of username where available
SELECT s.REFID
, s.jobnum
, s.customer
, e.username AS engineer
, a.username AS sales
FROM schedule s
LEFT
JOIN users e
ON e.id = s.engineer
LEFT
JOIN users a
ON a.id = s.sales
Using a LEFT [OUTER] JOIN ensures that the rows from schedule will be returned when there isn't a matching row in the users table. For example, if you had a NULL in the sales column of a row in schedule, there wouldn't be a matching row in the users table. With an [INNER] JOIN, the row from schedule would not be returned. But the query above does return the row, but with a NULL for the username when matching rows are not found.
If the engineer and sales columns are defined as NOT NULL, and foreign keys are defined and enforced, then the LEFT keyword can be omitted from the query above. In the more general case, where foreign keys are not enforced (e.g. MyISAM) or not defined, or the columns are nullable, we'd generally want the LEFT keywords.
UPDATE
Removing the LEFT keywords from the query will produce a query equivalent to that in the answer from Alvin Lee, which implements INNER JOIN operations.
The query from Alvin Lee will EXCLUDE rows from schedule that have a value in the engineer or sales column that is NULL, or has a value that does not match a value found in the id column of the users table.
To identify if any rows in the schedule table are not being returned by the query using an INNER JOIN, you can run a query that does an anti-join pattern.
-- find rows in schedule that don't have matching row in users
SELECT s.REFID
, s.jobnum
, s.customer
, s.engineer
, s.sales
FROM schedule s
LEFT
JOIN users e
ON e.id = s.engineer
LEFT
JOIN users a
ON a.id = s.sales
WHERE a.id IS NULL
OR e.id IS NULL
try this:
select sc.REFID, sc.jobnum, sc.customer, us.username as engineer, us.username as sales
from schedules as sc
left join users as us on sc.engineer = us.ID and sc.sales = us.ID
This query is working fine. It gives a count of contest entrants for whom the contact id in contest_entries is their origin_contact in the person table.
SELECT c.handle, COUNT(*)
FROM `contest_entry` ce,
person p,
contest c
WHERE
p.origin_contact = ce.contact AND
c.id = ce.contest
GROUP BY c.id
I want to now query how many of those records also have at least one record where the contact id matches in email_list_subscription_log BUT that table may have many log records for any one contact id.
How do I write a join that gives me a count that is not inflated by the multiple records?
Should I use a version of my first query to get all of the contact ids into a tmp table and just use that?
Not sure which field is contact id, but you can do something like this:
select c.handle,
count(*) as count
from `contest_entry` ce
inner join person p on p.origin_contact = ce.contact
inner join contest c on c.id = ce.contest
where exists (
select 1
from email_list_subscription_log l
where l.contact_id = ce.contact
)
group by c.id
You ought to deflate the email_list_subscription_log with DISTINCT or GROUP:
SELECT c.handle, COUNT(*)
FROM `contest_entry` ce
JOIN person p ON (p.origin_contact = ce.contact)
JOIN contest c ON (c.id = ce.contest)
JOIN (SELECT DISTINCT contact, email FROM email_list_subscription_log ) AS elsuniq
ON (ce.contact = elsuniq.contact)
[ WHERE ]
GROUP BY c.id
Using GROUP in the subquery you might count the number of records while still returning one row per element:
JOIN (SELECT contact, count(*) AS elsrecords FROM email_list_subscription_log
GROUPY BY contact) AS elsuniq
With this JOIN syntax, the WHERE is not necessary, but I kept it there if you need additional filtering.