I have two tables in mysql with the following structure:
Events: id
Events_artists: event_id, more columns
I would like to find the event_ids in the table events_artists that do not have a match with the id in events.
The only thing I have come up with so far is this:
SELECT * FROM events,events_artists WHERE events_artists.event_id!=events.id
However, that is crap and basically returns the whole table.
Does anyone know how to solve this?
Thank you!
Charles
SOLUTION FOUND, thanks to Andrzej Bobak
select * from events_artists where event_id not in (select id from events)
How about this approach?
select * from events_artists where event_id is null or event_id not in (select id from events)
select * from events_artists a
left join events b on a.id = b.id
where b.id is null
your approach uses a cartesian product which joins every row with each other. So your where criteria just filters your result containing the rows that don't match, but that will be a lot because of the cartesian product
Related
I'm kind of noobie to this, but I'm trying to learn, I have two tables, the first one (NEWS) has all the information about posts of a blog, it has the follow structure:
* NEWS (TABLE 1)
- id_new
- id_category
- date
- ...etc
- **likes**
and I have a second table:
* LIKES (TABLE 2)
- id_like
- id_new
- id_user
- date
- ip_user
So, I want to select all the rows from TABLE 1 to display all the news but also i want to count the likes and get the COUNT of each new as like column.
This approach left joins the NEWS table to a subquery which finds the number of likes for each news story.
SELECT
t1.*,
COALESCE(t2.likes, 0) AS likes
FROM NEWS t1
LEFT JOIN
(
SELECT id_new, COUNT(*) AS likes
FROM LIKES
GROUP BY id_new
) t2
ON t1.id_new = t2.id_new
Note that here a story having no likes would not appear at all in the LIKES table and would receive a count of zero. Also note that I assume that every record in the LIKES table corresponds to a logical like. If not, then the query could be modified to count something else.
You can do it like this
SELECT table1.*, table2.*, count(table2.id_like) as like FROM news AS table1
INNER JOIN likes AS table 2 ON table1.id_new = table2.id_new;
OR
SELECT table1.*, table2.*, count(table2.id_like) as like FROM news AS table1
LEFT JOIN likes AS table 2 ON table1.id_new = table2.id_new;
you can use prepared statement
for example
$stmt = $pdo->prepare("SELECT count(*) FROM TABLE_1);
$stmt2 = $pdo->prepare("SELECT count(*) FROM TABLE_2);
//then execute
just read more on prepared statement
Try this
SELECT n, (SELECT count(*) FROM like l WHERE l.id_new = n.id_new) FROM news n
Use something like :
SELECT *, (SELECT COUNT(*) FROM LIKES WHERE LIKES.id_new =id_new) AS newsLikesCount FROM NEWS ORDER BY date;
This query would return all news and their number of likes
select n1.* , numberOfLikes.number_of_likes
from news n1
left join
(select n.id_news, count(l.id_like) as number_of_likes
from news n
left join likes l on n.id_news = l.id_new
group by n.id_news) numberOfLikes on n1.id_news = numberOfLikes.id_news
The important concepts here is understanding how two tables are joined together (1), how group by works(2), and how to aggregate l.id_likes using count(3).
(1). Left join preserves everything in the NEWS table and join them
with news link to the news.
(2). Then we group the rows base on id_news from the news. However,
mysql gets confused because it doesn't know what to do with id_like
from the likes table that we included in our select clause. Don't
worry my friend, This is where count comes in.
(3). We count the number of id_likes base for each id_news since we
are grouping the rows base on id_news.
I hope this helps. and welcome to StackOverfow. If you find this answer of any other answer helpful please mark it as the solution. That way it will help the community and fellow programmers in the future if they run into the same problem as you. Cheers.
Edit: to include all columns from news table we simply join the result from above back to the news table itself. and we select everything from the news table n1 and only number_of_likes from the result we created above.
We need to grab the last and newest 20 entries from different tables. However, the GROUP BY statement skips records because we are working with LEFT JOIN on tables.
All these records are linked to unique persons in another table. We store these person's id's in an array for more queries later.
We have a few tables (in which all those person id's are stored) and we want to get them sorted and grouped.
The tables are like this:
SELECT lastRecord+personID FROM t1
SELECT lastRecord+personID FROM t2
SELECT lastRecord+personID FROM t3
SELECT lastRecord+personID FROM t4
WHERE t5.Essential_Column_Name = '1'
GROUP BY personID
ORDER BY 'all the latest entries'
LIMIT 20
With that, the relevance of all the latest entries should be equal.
We do have a timestamp column as well. Perhaps that might work better.
Any input is highly appreciated!
For people looking for an answer on this; this is the right post, answer and update to this Q:
UNION mysql gives weird numbered results
With thanks to all for the ideas and providing the paths to the right solution.
I use php and mysql. I have two tables,
table A (Id: auto-increment , idno)
table B (Id:auto-increment, sidno).
Table A contains about 3000 records and Table B contains about 27000 records. I want to search whether each of the records in table A exist in table B, if not print the records that does not exist in table B.
I tried to retrieve the records in table A and checking them against table A, but I could not succeed. And it took a very long time to finished the query.
And I have searched throughout but could not get something like this.
Please can anybody help me.
Thanks!
The following query might return all the idno which are not in table B
SELECT * FROM tableA WHERE `idno` NOT IN (SELECT `sidno` FROM tableB)
SQL Fiddle Demo
Ok. Try this:
SELECT tableB.Id, tableB.sidno
FROM tableA
RIGHT JOIN tableB ON tableA.Id = tableB.ID
WHERE tableA.Id = 'NULL';
This should give you all the records you want.
like this
select * from tableA where Minus select id from where tableA.id=tableB.id;
MINUS
http://www.techonthenet.com/sql/minus.php
Try this
SELECT * FROM table2 t where sid NOT IN (select id from table1) ;
Demo
What I'm trying to do
I have two tables, one for events, and one that says whether each event id has been seen. I want to create a query that joins both tables on event.id and seen.eventid. However, I would only like to return the rows which have not been seen, ordered by how recent they are.
What I have right now
This is the query which works for returning all the events which have already been seen:
SELECT *
FROM `events`
JOIN `seen` ON (`seen`.`event_id`=`event`.`id`)
//This is not part of the question but I might as well paste the entire code
//WHERE `user_id`='34'
//AND (`meta_id`='45' OR `meta_id`='37' OR `meta_id`='43')
GROUP BY `event_id`
ORDER BY `event`.`date` DESC
How do I reverse the query so that those returned are the rows in event that are not matched by this query?
We don't know your table structures so I'm just guessing...
SELECT *
FROM events e
LEFT
JOIN seen s
ON s.event_id = e.id)
AND s.user_id=34
WHERE e.meta_id IN (45,37,43)
AND s.event_id IS NULL
GROUP
BY e.event_id
ORDER
BY e.date DESC
I have a table with around 15 columns. What I would like to be able to do, is select a range of IDs and have all column data that is the same, presented to me.
At the minute, I have it structured as the following:
SELECT id, col_a, col_b ... count(id)
FROM table
GROUP BY col_a, col_b ...
Which returns rows grouped together that have identical data within all the rows - which is half what I want, but ideally I would like to be able to get a single row with either the value (if it's the same for every row id) or NULL if there is a single difference.
I'm not sure that it is possible, but I would rather see if it's doable in an SQL query than write some looping logic for PHP to go through and check each row's similarity.
Thanks,
Dan
UPDATE:
Just to keep this up-to-date, I worked through the problem by writing a PHP function that would find which were duplicates and then display the differences. However I have now since made a table for each column, and made the columns as references to the other tables.
E.G. In MainTable, ColA now refers to the table ColA
I'm still solving the problem with the PHP for the time being, mainly as I think it still leaves the problem mentioned above, but at least now Im not storing duplicate information.
Its a hairy thing to do, but you could do it similarly to how David Martensson suggested, I would write it like this, however:
Select a.id, a.col1, a.col2, a.col3
FROM myTable a, myTable b
WHERE a.id != b.id
and a.col1 = b.col1
and a.col2 = b.col2
and a.col3 = b.col3
That would give you the ids that are unique, but each result would have the same values for columns 1, 2, and 3. However, I agree with some of the commenters to your question that you should consider an alternative data structure, as this could better take advantage of an RDBMS model. In that case you would want to have 2 tables:
Table name: MyTableIds
Fields: id, attrId
Table name: MyTableAttrs
Fields: attrId, attr1, attr2, attr3, ect
In general, if you have data that is going to be duplicated for multiple records, you should pull it into a second table and create a relationship so that you only have to store the duplicated data 1 time and then reference it multiple times.
Make a join to a subquery with the group by:
SELECT a.id, b.col_a, b.col_b ... b.count)
FROM table a
LEFT JOIN (
SELECT id, col_a, col_b ... count(id) "count"
FROM table GROUP BY col_a, col_b ...
)b on a.id = b.id
That way the outer will select all rows.
If you still want to group answers you could use a UNION instead
SELECT id, col_a ...
WHERE id NOT IN ("SUBQUERY WITH GROUP BY")
UNION
"SUBQUERY WITH GROUP BY"
Not the nicest solution but it should work
It seems doable from how I have understood your question.
And here's a possible pattern:
SELECT
/* GROUP BY columns */
col_A,
col_B,
...
/* aggregated columns */
CASE MIN(col_M) WHEN MAX(col_M) THEN MIN(col_M) ELSE NULL END,
CASE MIN(col_N) WHEN MAX(col_N) THEN MIN(col_N) ELSE NULL END,
...
COUNT(...),
SUM(...),
WHATEVER(...),
...
FROM ...
GROUP BY col_A, col_B, ...