i Need some help.. i have some case like this below
i have 2 table.. call ("in_table" and "out_table")
data "in_table" look like
stock_id item_id date qty_in
-----------------------------------------
1 11 2017-07-11 12
2 11 2017-07-11 10
3 12 2017-07-11 10
4 12 2017-07-19 10
And i have "out_table" is like
id_tr item_id date qty_out
-------------------------------------
1 11 2017-07-19 2
1 12 2017-07-19 1
2 11 2017-07-19 2
2 12 2017-07-19 1
And i want to combine the date and display all the data like this,
Update: the join is by item_id but i want to select by date
date item_id qty_in qty_out
---------------------------------------
2013-07-11 11 22 0
2013-07-11 12 10 0
2013-07-19 11 0 4
2013-07-19 12 10 2
Thank you for your help.
It looks like you need kind of a full outer join of two aggregate subqueries. But in your case I would get item_id and date in a union subquery (derived table) and the sums in correlated subqueries (subselect).
select item_id, date,
(select sum(qty_in) from in_table i where i.item_id = sub.item_id and i.date = sub.date) as qty_in,
(select sum(qty_out) from out_table o where o.item_id = sub.item_id and o.date = sub.date) as qty_out
from (
select item_id, date from in_table
union
select item_id, date from out_table
) sub
order by date, item_id
Related
I want to join one to many table with single row on many table by limit 1 and order by create date
tbl_cart :
id fullname
1 myname1
2 myname2
3 myname3
tbl_cart_status:
id cart_id status created_at
1 1 33 2018-09-20
2 1 34 2018-09-23
3 2 34 2018-09-21
4 1 100 2018-09-25
5 2 35 2018-09-29
How can i get output with sql like this:
I want to get lastest status of my cart by ordered with created_at column
myname cart_id status created_at
myname1 1 100 2018-09-25
myname2 2 35 2018-09-29
Think filtering for this type of query:
select c.name, cs.*
from tbl_cart c join
tbl_cart_status cs
on c.id = cs.cart_id
where cs.created_at = (select max(cs2.created_at)
from tbl_cart_status cs2
where cs2.cart_id = cs.cart_id
);
Below are my database tables
left_table
id name
1 A
2 B
3 C
4 D
5 E
right_table
id left_table_id size date_time
1 1 xs 2017-06-13 14:20:00
2 3 s 2017-06-13 14:25:00
3 2 xs 2017-06-13 14:27:00
4 1 s 2017-06-13 14:30:00
5 2 m 2017-06-13 14:32:00
6 2 xs 2017-06-13 14:33:00
7 3 xl 2017-06-13 14:40:00
8 4 s 2017-06-13 14:41:00
9 4 m 2017-06-13 14:45:00
10 5 m 2017-06-13 14:46:00
How to write the sql query to get the records of the left_table order by the max(date_time) DESC where date_time <= NOW() as the following result.
result left_table order by max(add_time) DESC
id name max(add_time)
2 B 2017-06-13 14:33:00
1 A 2017-06-13 14:30:00
3 C 2017-06-13 14:25:00
This is because date_time of left_table_id of 4 and 5 is > NOW(). Assume NOW() = 2017-06-13 14::35:00. Note that left_table_id 3 has one add_time > NOW() but it is still being selected because it has other right record, add_time <= NOW().
You can use a query like the following:
SELECT t.id, t.name, r.date_time
FROM left_table AS t
JOIN (
SELECT id, MAX(date_time) AS date_time
FROM right_table
WHERE date_time <= NOW()
GROUP BY id) AS r ON t.id = r.id
ORDER BY r.date_time DESC;
The query uses a derived table which filters out records that have a date_time value that is past the current timestamp. It also group records in order to get the latest date_time value per id. Using this derived table we can easily perform the sorting required using its date_time field.
I have a table with a structure like this:
table_id | user_id | text | number_id | start_time
1 1 gdsgds 8 2015-10-11 07:14:44
2 2 vcxvc 8 2015-10-11 07:20:44
3 4 ewgs 8 2015-10-12 09:19:22
4 7 vvvcc 8 2015-10-13 18:12:23
etc.
I need to write a query that will return me the number of texts displayed each day on each number. So far I have the following query:
SELECT *
FROM
(
SELECT DATEDIFF(now(), start_time) AS days_ago,
COUNT(table_id) AS num_texts
FROM TABLE
GROUP BY DATE(start_time)
)
WHERE
(
days_ago <= 7
AND days_ago > 0
)
and this query returns me a table:
days_ago | num_texts
0 | 2
1 | 3
2 | 4
3 | 1
and that works almost fine, but I need to divide it by number_id too... How can I do it?
Add the column number_id to the select and group by in the subquery.
SELECT *
FROM
(
SELECT DATEDIFF(now(), start_time) AS days_ago,
number_id,
COUNT(table_id) AS num_texts
FROM TABLE
GROUP BY DATE(start_time), number_id
)
WHERE
days_ago <= 7
AND days_ago > 0
I have four Tables with four date coloumns respectively.
Table 1 ---------- Date 1
Table 2 ---------- Date 2
Table 3 ---------- Date 3
Table 4 ---------- Date 4
Now i want to get a day report in a month for all the four tables.if there is no data in any particular table for particular date it should dispaly NULL.How can i achieve it?
Structure:-
Table-1:-
ID Amount1 Date1
1 340 24/04/2013
2 200 04/04/2013
3 1000 15/04/2013
Table-2:-
ID Amount2 Date2
1 2000 22/04/2013
2 200 04/04/2013
3 1500 15/04/2013
Table-3:-
ID Amount3 Date3
1 3400 24/04/2013
2 200 19/04/2013
3 1800 15/04/2013
Table-4:-
ID Amount4 Date4
1 3200 24/04/2013
2 2200 04/04/2013
3 1000 18/04/2013
Now my result should be like
Date Amount1 Amount2 Amount3 Amount4
01/04/2013 Null Null Null Null
|
|
|
04/04/2013 200 200 null 2200
|
|
|
|
15/0402013 1000 1500 1800 null
|
|
|
|
|24/0402013 340 null 3400 3200
|
|
|
|
31/04/2013
Using a subquery to get a range of dates (I am assuming you want every day in April 2013) and then left joining that against the tables of data.
SELECT, dates.aDate, Table-1.Amount1, Table-2.Amount2, Table-3.Amount3, Table-4.Amount4
FROM
(
SELECT DATE_ADD('2013-04-01', INTERVAL (Units.i + Tens.i * 10) DAY) AS aDate
FROM
(SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) Units,
(SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) Tens
HAVING aDate <= '2013-04-30'
) dates
LEFT OUTER JOIN Table-1 ON Table-1.Date1 = dates.aDate
LEFT OUTER JOIN Table-2 ON Table-2.Date2 = dates.aDate
LEFT OUTER JOIN Table-3 ON Table-3.Date3 = dates.aDate
LEFT OUTER JOIN Table-4 ON Table-4.Date4 = dates.aDate
This assumes that there are not duplicate dates in any particular table.
You can try the following query
with dates as (
(select date from date1)union(select date from date2)union
(select date from date3)union (select date from date4) order by date asc)
select date,
(select amount from date1 where date=dt.date limit 1),
(select amount from date2 where date=dt.date limit 1),
(select amount from date3 where date=dt.date limit 1),
(select amount from date4 where date=dt.date limit 1)
from dates as dt;
You can add the date constraints on dates.
P.S.: Tested on PgSQL
I've 4 tables as shown below
doctors
id name
------------
1 Mathew
2 Praveen
3 Rosie
4 Arjun
5 Denis
doctors_appointments
id doctors_id patient_name contact date status
--------------------------------------------------------------------------------------
1 5 Nidhin 9876543210 2012-12-10 15:39:41 Registered
2 5 Sunny 9876543210 2012-12-18 15:39:48 Registered
3 5 Mani 9876543210 2012-12-12 15:39:57 Registered
4 2 John 9876543210 2012-12-24 15:40:09 Registered
5 4 Raj 9876543210 2012-12-05 15:41:57 Registered
6 3 Samuel 9876543210 2012-12-14 15:41:33 Registered
7 2 Louis 9876543210 2012-12-24 15:40:23 Registered
8 1 Federick 9876543210 2012-12-28 15:41:05 Registered
9 2 Sam 9876543210 2012-12-12 15:40:38 Registered
10 4 Sita 9876543210 2012-12-12 15:41:00 Registered
doctors_dutyplan
id doctor_id weeks time no_of_patients
------------------------------------------------------------------
1 1 3,6,7 9:00am-1:00pm 10
2 2 3,4,5 1:00pm-4:00pm 7
3 3 3,6,7 10:00am-2:00pm 10
4 4 3,4,5,6 8:30am-12:30pm 12
5 5 3,4,5,6,7 9:00am-4:00pm 30
emp_leave
id empid leavedate
--------------------------------
1 2 2012-12-05 14:42:36
2 2 2012-12-03 14:42:59
3 3 2012-12-03 14:43:06
4 3 2012-12-06 14:43:14
5 5 2012-12-04 14:43:24
My task is to find all the days in a month in which the doctor is available excluding the leave dates.
My query what is wrote is given below:
SELECT DATE_ADD( '2012-12-01', INTERVAL
ROW DAY ) AS Date,
ROW +1 AS DayOfMonth
FROM (
SELECT #row := #row +1 AS
ROW FROM (
SELECT 0
UNION ALL SELECT 1
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
UNION ALL SELECT 6
)t1, (
SELECT 0
UNION ALL SELECT 1
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
UNION ALL SELECT 6
)t2, (
SELECT #row := -1
)t3
LIMIT 31
)b
WHERE DATE_ADD( '2012-12-01', INTERVAL
ROW DAY )
BETWEEN '2012-12-01'
AND '2012-12-31'
AND DAYOFWEEK( DATE_ADD( '2012-12-01', INTERVAL
ROW DAY ) ) =2
AND DATE_ADD( '2012-12-01', INTERVAL
ROW DAY ) NOT
IN (
SELECT DATE_FORMAT( l.leavedate, '%Y-%m-%d' ) AS date
FROM doctors_dutyplan d
LEFT JOIN emp_leave AS l ON d.doctor_id = l.empid
WHERE doctor_id =2
)
This works fine for all doctors who took any leave in a particular day in a month (here in the example it is Decemeber 2012). and the result for the above query is shown below:
Date DayOfMonth
-----------------------
2012-12-10 10
2012-12-17 17
2012-12-24 24
2012-12-31 31
But on the other hand for the doctors who didn't took any leave , for that my query is showing empty table, example for the doctor Mathew whose id is 1, my query returns an empty result
can anyone please tell a solution for this problem.
Thanks in advance.
Your query is large, but this part looks fishy:
NOT IN (
SELECT DATE_FORMAT( l.leavedate, '%Y-%m-%d' ) AS date
FROM doctors_dutyplan d
LEFT JOIN emp_leave AS l ON d.doctor_id = l.empid
WHERE doctor_id =2
The left join means a null would be returned for doctor 1. Now, col1 not in (null) does not behave as you may expect. It translates to:
col1 <> null
Which is never true. You could solve this by changing the left join to an inner join, so an empty set instead of null is returned for a doctor without leave.