I want to get the id from first table, and the information in the second table but only if there is any related row in second table, AND where the greatest date of the related rows is smaller(earlier) than time right now...
This is what I have right now:
"SELECT t1.id as actID, t2.id AS eventsid, t2.controlled FROM `activites` t1
LEFT JOIN `events` t2 ON t2.activitesid = t1.id
WHERE t2.datum < UNIX_TIMESTAMP() GROUP BY t2.controlled"
And what I have been trying is something like
"SELECT t1.id as actID, t2.id AS eventsid, t2.controlled FROM `activites` t1
LEFT JOIN `events` t2 ON t2.activitesid = t1.id
WHERE (SELECT `datum` FROM `events` t3 WHERE t3.controlled = t2.controlled ORDER BY `datum` DESC LIMIT 1) < UNIX_TIMESTAMP() GROUP BY t2.controlled"
Is there anybody who can point me in wich direction to go or how to type this kind of query?
There is no need pointing out that I should use PDO, mysqli etc...
Related
I searched around and found a near example to what I'm looking for, but it doesn't work in my case.
I have a query that does an INNER JOIN on two tables and this join constrains my overall data set substantially. I then want to LEFT JOIN onto a third table but I only want one record from that third table. The reason for the left join is because not every result of the INNER JOIN has a match in the 3rd table. Something like this:
SELECT DISTINCT t1.code, t2.id, t2.code, t3.id, t3.source_title, t3.display_order
FROM table1 t1
INNER JOIN table2 t2 ON t2.code=t1.code AND t2.type=0
LEFT JOIN table3 t3 ON t3.code=t1.code
ORDER BY t1.code, t3.display_order
This query returns too many records because the third table contains multiple records with a matching code. I just want the first one that matches with the lowest display_order value and, unfortunately, I can't limit the records to have display_order=1 because the lowest display order is not always one.
IMPORTANT: The t3.id value (if any) returned by this query must correspond to the record with the lowest display_order value. I.e., it won't work if the query correctly returns the lowest display_order value but the t3.id value corresponds to some other record in table 3.
Is this even possible? Any help would be much appreciated.
EDIT: Per Nick's suggestion, I have tried this, which appears to be working. I'll do some verification and report back:
SELECT DISTINCT t1.code, t2.*, sq.id, sq.source_title, sq.display_order
FROM table1 t1
INNER JOIN table2 p ON t2.code=t1.code AND t2.type=0
LEFT JOIN (
SELECT t3.*
FROM table3 t3
WHERE t3.display_order=(
SELECT MIN(display_order)
FROM table3 t3a
WHERE t3a.code = t3.code
)
) sq ON sq.code=t1.code
ORDER BY t1.code, sq.display_order
You should be able to replace table3 in your LEFT JOIN with
(SELECT *
FROM table3 t3
WHERE display_order = (SELECT MIN(display_order)
FROM table3 t3a
WHERE t3a.code = t3.code)
) t3
In MySQL 8.0 you can try to use row_number() for each code and ordered by display_order in a subquery from table3. Then left join that result and check for the row_number() to be equal to 1.
SELECT DISTINCT
t1.code,
t2.id,
t2.code,
t3.id,
t3.source_title,
t3.display_order
FROM table1 t1
INNER JOIN table2 t2
ON t2.code = t1.code
LEFT JOIN (SELECT t3.id,
t3.source_title,
t3.display_order,
t3.code,
row_number() OVER (PARTITION BY t3.code
ORDER BY t3.display_order) rn
FROM table3 t3) t3
ON t3.code = t1.code
WHERE t2.type = 0
AND t3.rn = 1
ORDER BY t1.code,
t3.display_order;
In lower versions you can try correlated subqueries ordered by display_order and LIMIT 1 (to get only one record).
SELECT DISTINCT
t1.code,
t2.id,
t2.code,
(SELECT t3.id
FROM table3 t3
WHERE t3.code = t1.code
ORDER BY t3.display_order,
t3.id
LIMIT 1) id,
(SELECT t3.source_title
FROM table3 t3
WHERE t3.code = t1.code
ORDER BY t3.display_order,
t3.id
LIMIT 1) source_title,
(SELECT t3.display_order
FROM table3 t3
WHERE t3.code = t1.code
ORDER BY t3.display_order,
t3.id
LIMIT 1) display_order
FROM table1 t1
INNER JOIN table2 t2
ON t2.code = t1.code
WHERE t2.type = 0
ORDER BY t1.code,
(SELECT t3.display_order
FROM table3 t3
WHERE t3.code = t1.code
ORDER BY t3.display_order,
t3.id
LIMIT 1);
I assumed, that display_order in table3 isn't unique but id is. So I added id to the ORDER BY clauses in the subqueries to make sure the same record is selected in each of them. If display_order is unique, you can remove id FROM the ORDER BY clauses.
Edit:
If you don't want to repeat the subqueries in the (overall) ORDER BY clause, you can also order by the column ordinals. E.g.:
...
ORDER BY 1, 6;
I'm attempting to get a list of values that don't exist in another table for a specific date.
Table Layouts:
table1 (TABLE)
id INT(10)
table2 (TABLE)
id INT(10)
table1id INT(10)
dateupdated DATETIME(19)
SQLFiddle
Query that I thought would work that isn't.
SELECT t1.id FROM Table1 as t1
JOIN Table2 as t2
ON t1.id=t2.table1id
WHERE date(t2.dateupdated) != DATE(NOW())
I'm expecting id 7 and 8 to come back from the above query, since they don't exist in Table2. But I'm getting no rows back.
Reversing the Query to match = DATE(NOW()) gives me the lines that do have matches
SELECT t1.id FROM Table1 as t1
JOIN Table2 as t2
ON t1.id=t2.table1id
WHERE date(t2.dateupdated) = DATE(NOW())
Response:
id
1
2
3
4
5
6
9
10
Any guidance would be appreciated, I'm still learning MySQL. But I'm missing something very simple here.
http://sqlfiddle.com/#!9/7a9fc/11
SELECT t1.id FROM Table1 as t1
LEFT JOIN Table2 as t2
ON t1.id=t2.table1id
AND date(t2.dateupdated) = DATE(NOW())
WHERE t2.id IS NULL;
Since there is always more than one way, another way is using the NOT IN operator with a subquery (since MySQL doesn't support MINUS).
SELECT t1.id FROM Table1 as t1
WHERE t1.id NOT IN
(SELECT t2.table1id FROM Table2 as t2
WHERE date(t2.dateupdated) = DATE(NOW()))
For DBMS that do support MINUS, you could do:
SELECT t1.id FROM Table1 as t1
MINUS
SELECT t2.table1id FROM Table2 as t2
WHERE date(t2.dateupdated) = DATE(NOW())
This is the way that I prefer to do it:
SELECT id FROM Table1
WHERE id not in (select table1id from Table2 where date(dateupdated) = date(NOW()))
Learning mysql I found this invaluable reference: http://blog.codinghorror.com/a-visual-explanation-of-sql-joins/
Hope you find it useful!
Since the JOIN doesn't retrieve NULL rows, you have to use a LEFT or RIGHT JOIN to deal with empty ROWS.
here us the query
SELECT *
FROM Table1
WHERE complete='Y'
AND shipped='Y'
AND active='Y'
AND create_dttm > '2013-10-10 08:28:41'
AND order_id IN
(SELECT DISTINCT t1.order_id
FROM Table2 t1
INNER JOIN table3 t2 ON t1.prod_id = t2.prod_id
WHERE t2.prod_sku LIKE '%D-600%'
AND t1.create_dttm > '2013-02-15 08:28:41')
You are using a sub-query in WHERE clause, that could be the main reason behind slow execution of your query. Try using JOINS instead of sub query.
SELECT t1.*
FROM Table1 t1
INNER JOIN Table2 t2 ON T1.order_id = T2.order_id
AND t2.create_dttm > '2013-02-15 08:28:41'
INNER JOIN table3 t3 ON t2.prod_id = t3.prod_id
AND t3.prod_sku LIKE '%D-600%'
WHERE complete='Y'
AND shipped='Y'
AND active='Y'
AND create_dttm > '2013-10-10 08:28:41'
And also check for indexes on your tables.
I am trying to count row numbers on an another table and use HAVING to select only rows greater than 0.
SELECT COUNT(t3.ID),t1.ID,t2.sell,t1.date
FROM `album` t1
INNER JOIN `members` t2 ON t2.aID = t1.ID
INNER JOIN `table` t3 ON t3.rID = t1.ID
WHERE t1.date <= '$dt' AND t2.sell = '1'
ORDER BY t1.date DESC
HAVING COUNT(t3.ID) > 0
It doesnt work. where am i wrong ?
Thanks
You need a GROUP BY clause so that MySQL knows how to group the data when you're using aggregate functions such as COUNT.
SELECT COUNT(t3.ID),t1.ID,t2.sell,t1.date
FROM `album` t1
INNER JOIN `members` t2 ON t2.aID = t1.ID
INNER JOIN `table` t3 ON t3.rID = t1.ID
WHERE t1.date <= '$dt' AND t2.sell = '1'
GROUP BY t1.ID,t2.sell,t1.date
HAVING COUNT(t3.ID) > 0
ORDER BY t1.date DESC
For more information, see this.
First up, apologies for the awful title I couldn't think of a better way to articulate my issue. (Feel free to suggest better altnernatives)
Basically I have a table with a "count" column.
I want to reset all counts to zero except for the 10 rows with the top values. I want them to be reset to 0.
How do I achieve this without writing multiple queries?
Update
I have my query as the following now
UPDATE covers AS t1
LEFT JOIN (SELECT t.cover_id
FROM covers t
ORDER BY t.cover_views DESC
LIMIT 10) AS t2 ON t2.id = t.id
SET cover_views = 0
WHERE t2.id IS NULL
I get the error #1054 - Unknown column 't2.id' in 'where clause' - any idea why?
I also tried the following with the same result
UPDATE covers t1
LEFT JOIN (SELECT t.cover_id
FROM covers t
ORDER BY t.cover_views DESC
LIMIT 10) t2 ON t2.id = t.id
SET t1.cover_views = 0
WHERE t2.id IS NULL
Use:
UPDATE TABLE t1
LEFT JOIN (SELECT t.id
FROM TABLE t
ORDER BY t.id DESC
LIMIT 10) t2 ON t2.id = t1.id
SET TABLE.count = 0
WHERE t2.id IS NULL
try:
update <table> t
left outer join
(
select id from <table> order by <counter> desc limit 10
) c on c.id = t.id
set
<counter> = 0
where
c.id is null;
You can use a subquery:
update A set count = 0 where A.id not in
(select id from A order by count desc limit 10)