I'm having difficulties with creating a sql query that selects a joining of 2 tables where the relationship doesn't exists in a third table.
To be more specific I try to explain it with an example.
I have a table member, form and member_form.
When a member inserts an answer in the form, it's saved in the member_form table.
The forms can be active, and have a deadline.
So what I want is to return a result for each member and the form he still didn't fill in. But the form must be active, and deadline must be for example 2018-03-15. I don't know the amount of members or forms. So I can't say from select * where member id is = x.
This is needed to send a reminder mail to all the users that didn't fill in the form yet for a specific date.
member
id | name | email
--------------------------
1 | Test | test#email.com
2 | test2 | test2#email.com
4 | test4 | test4#email.com
5 | test5 | test5#email.com
6 | test6 | test6#email.com
7 | test7 | test7#email.com
form
id | insert_date | deadline_date | active
---------------------------------------------------------------
1 | 2018-03-15 00:00:00 | 2018-03-15 00:00:00 | 1
2 | 2018-02-10 00:00:00 | 2018-05-15 00:00:00 | 0
3 | 2018-03-15 00:00:00 | 2018-03-15 00:00:00 | 1
5 | 2018-03-15 00:00:00 | 2018-06-15 00:00:00 | 1
6 | 2018-03-15 00:00:00 | 2018-05-15 00:00:00 | 1
7 | 2018-03-15 00:00:00 | 2018-04-15 00:00:00 | 0
member_form
member_id | form_id | answer
--------------------------------------
1 | 6 | 1
1 | 2 | 2
1 | 5 | 1
2 | 2 | 1
2 | 3 | 1
4 | 6 | 2
5 | 6 | 3
5 | 7 | 2
6 | 1 | 2
7 | 2 | 1
Result
member_id | name | email | form_id | insert_date | deadline_date | active
-------------------------------------------------------------------------------------------------------------------
2 | test2 | test2#email.com | 6 | 2018-03-15 00:00:00 | 2018-05-15 00:00:00 | 1
6 | test6 | test6#email.com | 6 | 2018-03-15 00:00:00 | 2018-05-15 00:00:00 | 1
7 | test7 | test7#email.com | 6 | 2018-03-15 00:00:00 | 2018-05-15 00:00:00 | 1
SELECT * FROM form AS f , member AS m WHERE f.deadline_date = '2018-05-15 00:00:00' AND f.active = 1 and !exists(select * FROM member_form AS amf WHERE amf.member_id = am.id And amf.form_id = af.id);
Try this
SELECT * FROM Member m, Form f
WHERE CONCAT(m.id,':',f.id) NOT IN
(SELECT CONCAT(mf.member_id, ':', mf.form_id) FROM Member_form mf)
AND f.deadline_date = '2018-05-15'
AND f.active = 1
Related
I have a table with 4 columns: ID, fieldDATE, fieldINT1, fieldINT2.
Table is like this:
ID| fieldDate | FieldINT1 | FiledINT2 |
===================================
1 | 2016-01-01 | 100 | 1 |
2 | 2016-01-08 | 200 | 1 |
3 | 2016-02-01 | 150 | 1 |
4 | 2016-02-05 | 400 | 2 |
5 | 2017-01-01 | 120 | 1 |
6 | 2017-01-21 | 123 | 1 |
7 | 2017-02-03 | 30 | 1 |
8 | 2018-01-01 | 123 | 1 |
9 | 2018-01-03 | 30 | 1 |
I'd like to create a table with 12 rows, with the first column is the month name, and the other columns are sum of fieldINT1 and fieldINT2, group by month in a specific YEAR. So in my example, there will be 4 columns ( MONTH NAME, 2016, 2017, 2018)
How can I do it?
I have this table:
+----+--------+------------+-----------+------------------+
| id | amount | period | player_id | payment_category |
+----+--------+------------+-----------+------------------+
| 3 | 100 | 2017-06-01 | 1 | 1 |
| 10 | 100 | 2017-06-01 | 2 | 1 |
| 6 | 100 | 2017-08-01 | 2 | 1 |
| 5 | 100 | 2017-10-01 | 3 | 1 |
| 2 | 100 | 2017-11-01 | 2 | 1 |
| 4 | 100 | 2017-11-01 | 1 | 1 |
| 1 | 100 | 2017-12-01 | 1 | 1 |
| 7 | 100 | 2017-12-01 | 1 | 1 |
| 9 | 100 | 2017-12-01 | 2 | 1 |
| 11 | 200 | 2017-12-01 | 1 | 3 |
+----+--------+------------+-----------+------------------+
Current result:
2017-06-01 2
2017-08-01 1
2017-10-01 1
2017-11-01 2
2017-12-01 3
Desired result:
2017-06-01 2
2017-07-01 0
2017-08-01 1
2017-09-01 0
2017-10-01 1
2017-11-01 2
2017-12-01 3
How can I do that? I tried with coalesce and ifnull. No luck.
I started with DQL:
$query = $em->createQuery('
SELECT COUNT(p.id) as total, p.period
FROM AppBundle:Payment p
WHERE p.period >= :fromTime
AND p.period <= :toTime
AND p.paymentCategory = 1
GROUP BY p.period
')
Of course this does not return the results for missing months ;) I'm looking for a method (doctrine or native mysql) which will somehow fill in the missing months. They can't be hardcoded - I need the results from last x months. Is it even possible or I should do it in PHP?
I have a table auctions and a table lots:
mysql> select id, auction_name, auction_startdate, auction_planned_closedate from auctions;
+----+--------------+---------------------+---------------------------+
| id | auction_name | auction_startdate | auction_planned_closedate |
+----+--------------+---------------------+---------------------------+
| 1 | Auction 1 | 2016-05-01 00:00:00 | 2016-06-30 00:00:00 |
| 2 | Auction 2 | 2016-06-01 00:00:00 | 2016-07-30 00:00:00 |
| 3 | Auction 3 | 2016-07-01 00:00:00 | 2016-08-30 00:00:00 |
| 4 | Auction 4 | 2016-09-01 00:00:00 | 2016-10-30 00:00:00 |
+----+--------------+---------------------+---------------------------+
mysql> select id, auction_id, lot_name from lots;
+----+------------+----------+
| id | auction_id | lot_name |
+----+------------+----------+
| 1 | 1 | Lot 1 |
| 2 | 1 | Lot 2 |
| 3 | 1 | Lot 3 |
| 4 | 1 | Lot 4 |
| 5 | 1 | Lot 5 |
| 6 | 1 | Lot 6 |
| 7 | 1 | Lot 7 |
| 8 | 2 | Lot 8 |
| 9 | 2 | Lot 9 |
| 10 | 2 | Lot 10 |
| 11 | 3 | Lot 11 |
| 12 | 3 | Lot 12 |
| 13 | 3 | Lot 13 |
| 14 | 3 | Lot 14 |
| 15 | 4 | Lot 15 |
| 16 | 4 | Lot 16 |
+----+------------+----------+
I want to display only the lots for current auctions (which are auctions 1 and 2 in the example), in other words for which the current time is between the 'auction_startdate' and 'auction_planned_closedate'.
So here is what I want to achieve:
+--------------+---------------------+---------------------------+---------+
| auction_name | auction_startdate | auction_planned_closedate | lots_id |
+--------------+---------------------+---------------------------+---------+
| Auction 1 | 2016-05-01 00:00:00 | 2016-06-30 00:00:00 | 1 |
| Auction 1 | 2016-05-01 00:00:00 | 2016-06-30 00:00:00 | 2 |
| Auction 1 | 2016-05-01 00:00:00 | 2016-06-30 00:00:00 | 3 |
| Auction 1 | 2016-05-01 00:00:00 | 2016-06-30 00:00:00 | 4 |
| Auction 1 | 2016-05-01 00:00:00 | 2016-06-30 00:00:00 | 5 |
| Auction 1 | 2016-05-01 00:00:00 | 2016-06-30 00:00:00 | 6 |
| Auction 1 | 2016-05-01 00:00:00 | 2016-06-30 00:00:00 | 7 |
| Auction 2 | 2016-06-01 00:00:00 | 2016-07-30 00:00:00 | 8 |
| Auction 2 | 2016-06-01 00:00:00 | 2016-07-30 00:00:00 | 9 |
| Auction 2 | 2016-06-01 00:00:00 | 2016-07-30 00:00:00 | 10 |
+--------------+---------------------+---------------------------+---------+
The following query gets me the current auctions:
mysql> select auction_name, auction_startdate, auction_planned_closedate from auctions where now() >= auction_startdate and now() <= auction_planned_closedate;
+--------------+---------------------+---------------------------+
| auction_name | auction_startdate | auction_planned_closedate |
+--------------+---------------------+---------------------------+
| Auction 1 | 2016-05-01 00:00:00 | 2016-06-30 00:00:00 |
| Auction 2 | 2016-06-01 00:00:00 | 2016-07-30 00:00:00 |
+--------------+---------------------+---------------------------+
and then I do an inner join with the 'lots' table:
select auction_name, auction_startdate, auction_planned_closedate, lots.id
from auctions
where now() >= auction_startdate
and now() <= auction_planned_closedate
inner join lots on auctions.id = lots.auction_id;
ERROR 1064 (42000): You have an error in your SQL syntax; check the
manual that corresponds to your MySQL server version for the right
syntax to use near 'inner join lots on auctions.id=lots.auction_id' at
line 1
I'm getting a syntax error which I'm staring blind at for a while.
Wrong order, put the WHERE clause after the JOIN:
select auction_name, auction_startdate, auction_planned_closedate, lots.id
from auctions
inner join lots on auctions.id = lots.auction_id
where now() >= auction_startdate
and now() <= auction_planned_closedate
Your join is in the wrong order:
select a.auction_name, a.auction_startdate, a.auction_planned_closedate, l.id
from auctions a inner join
lots l
on a.id = l.auction_id
where now() >= a.auction_startdate and now() <= a.auction_planned_closedate ;
Notes:
where goes after the from clause. join is not a separate clause; it is an operator in the from clause.
Table aliases make a query easier to write and to read.
Qualify all the column names. This makes it clear where the columns are coming from.
My table is as follow:
-------------------------------------------
| rec_id | A_id | B_id |Date(YYYY-MM-DD)|
-------------------------------------------
| 1 | 1 | 6 | 2014-01-01 |
| 2 | 5 | 1 | 2014-01-02 |
| 3 | 2 | 6 | 2015-01-03 |
| 4 | 6 | 1 | 2014-01-04 |
| 5 | 7 | 1 | 2014-01-05 |
| 6 | 3 | 6 | 2014-01-06 |
| 7 | 8 | 1 | 2014-01-07 |
| 8 | 4 | 6 | 2014-01-08 |
| 9 | 9 | 1 | 2014-01-09 |
| 10 | 10 | 21 | 2014-01-10 |
| 11 | 12 | 21 | 2014-01-11 |
| 12 | 11 | 2 | 2014-01-12 |
| 13 | 1 | 1 | 2014-12-31 |
| 14 | 2 | 2 | 2014-12-31 |
| 15 | 1 | 1 | 2015-01-31 |
| 16 | 10 | 21 | 2015-01-31 |
| 17 | 1 | 21 | 2014-10-31 |
This table represents the possession of various "A_id" to a specific "B_id" with a date when it is possessed. The possession of each "A_id" can be changed later on at any time. That means the only the latest possession is considered.
I want to find out all the "A_id" that are currently (possessed in latest date) in possession of a specific "B_id". For example, for "B_id" = 6 the possessed "A_id" at present are as follows:
---------------------------
| A_id | Date(YYYY-MM-DD) |
---------------------------
| 2 | 2015-01-03 |
| 3 | 2014-01-06 |
| 4 | 2014-01-08 |
Similarly, for "B_id" = 21 the possessed "A_id" at present are as follows:
---------------------------
| A_id | Date(YYYY-MM-DD) |
---------------------------
| 10 | 2015-01-31 |
| 12 | 2014-01-11 |
I would highly appreciate your kind help in this regard.
One way to accomplish this is to use a correlated not exists predicate that makes sure that there doesn't exists any later possession for each A_ID with another B_ID.
SELECT A_ID, MAX(PDATE) AS DATE
FROM YOUR_TABLE T
WHERE B_ID = 6
AND NOT EXISTS (
SELECT 1
FROM YOUR_TABLE
WHERE A_ID = T.A_ID
AND PDATE > T.PDATE
AND B_ID <> T.B_ID
)
GROUP BY A_ID
let's assume i have follow table
| ID | teamid | timestamp |
| 5 | 1 | 2013-07-27 10:19:00 |
| 6 | 2 | 2013-07-27 10:20:00 |
| 7 | 1 | 2013-07-27 10:25:00 |
| 8 | 3 | 2013-07-27 10:26:00 |
| 9 | 1 | 2013-07-27 10:28:00 |
| 10 | 2 | 2013-07-27 10:29:00 |
| 11 | 3 | 2013-07-27 10:30:00 |
| 13 | 3 | 2013-07-27 10:31:00 |
What i need is the records where the interval between the timestamp is lower then 4 minutes and grouped by the team id
so output need looks like
| 7 | 1 | 2013-07-27 10:25:00 |
| 9 | 1 | 2013-07-27 10:28:00 |
| 11 | 3 | 2013-07-27 10:30:00 |
| 13 | 3 | 2013-07-27 10:31:00 |
can someone show me the correct way to solve
tnx
The following sql statement will return your desired list:
SELECT table1.id, table1.teamid, table1.timestamp
FROM exampleTable table1, exampleTable table2
where table1.id != table2.id AND
table1.teamid = table2.teamid AND
ABS(table1.timestamp - table2.timestamp) < 400
ORDER BY teamid, id