I am new to MYSQl, Please help me out..
Following query is partially working fine, but for some rows its double the values, it happens when both tables have a same date in two or more rows like here 2015-08-11 are 3 in first table and 2 in another table.
select all_dates.value1 as "Date",
sum(coalesce(g.Qty1, '-')) as "Inward(B_Qty)",
sum(coalesce(f.Qty2, '-')) as "Outward(B_Qty)"
from
( select distinct Date1 as value1 from inward where Name = 'A' union
select distinct Date2 from outward where Name = 'A'
) as all_dates
left join inward g
on g.Date1 = all_dates.value1 and g.Name = 'A'
left join outward f
on f.Date2 = all_dates.value1 and f.Name = 'A' group by all_dates.value1,f.Date2
table no. 1 :- Inward
Name Qty1 Date1
A 25000 2015-08-11
A 15000 2015-08-12
A 45000 2015-08-11
B 150000 2015-09-11
B 85000 2015-07-08
B 15000 2015-07-08
table no 1:Outward
Name Qty2 Date2
A 15000 2015-08-01
A 25000 2015-08-09
A 15000 2015-08-11
A 45000 2015-08-11
B 25000 2015-07-25
Expected OUtput
Date Inward Outward
2015-08-11 70000 60000
2015-08-09 - 25000
2015-08-01 - 15000
2015-08-12 15000 -
Actual ouput:
Date Inward(B_Qty) Outward(B_Qty)
2015-08-01 0 15000
2015-08-09 0 25000
2015-08-11 140000 120000
2015-08-12 15000 0
third rows of actual output is doubling the values..Why it is happening dont know.
Try joining to derived tables already containing sums per Date1, Date2:
select all_dates.value1 as `Date`,
coalesce(`Inward(B_Qty)`, '-') as `Inward(B_Qty)`,
coalesce(`Outward(B_Qty)`, '-') as `Outward(B_Qty)`
from
(
select distinct Date1 as value1 from inward where Name = 'A' union
select distinct Date2 from outward where Name = 'A'
) as all_dates
left join
(
select `Date1`, sum(Qty1) AS `Inward(B_Qty)`
from inward
where Name = 'A'
group by `Date1`
) as g
on g.Date1 = all_dates.value1
left join
(
select `Date2`, sum(Qty2) AS `Outward(B_Qty)`
from outward
where Name = 'A'
group by `Date2`
) as f
on f.Date2 = all_dates.value1
group by all_dates.value1
Demo here
Try this way:
select all_dates.value1 as "Date",
sum(coalesce(g.Qty1, '-')) as "Inward(B_Qty)",
sum(coalesce(f.Qty2, '-')) as "Outward(B_Qty)"
from
( select distinct value1 from (Select Date1 as value1 from inward where Name = 'A' union
select Date2 from outward where Name = 'A') as TmpDates
) as all_dates
left join inward g
on g.Date1 = all_dates.value1 and g.Name = 'A'
left join outward f
on f.Date2 = all_dates.value1 and f.Name = 'A' group by all_dates.value1,f.Date2
Related
I have below mentioned table:
ID Type Date Status1 Status2 Status3
1 458 2018-01-01 15:04:06 AAA A B
2 471 2017-12-31 15:04:06 AAA A B
3 458 2018-01-15 15:04:06 BBC C D
5 458 2018-01-18 15:04:06 AAA X D
There are many same value in Type column, i want to fetch the data with below mentioned condition:
Where any value in Type (should have more than one time in table) have Status1 as AAA and other rows with same value in Type are greater than Previous Date, with Status2 as C and Status3 as D together or Status3 must be D.
Output:
ID Type Date Status1 Status2 Status3
1 458 2018-01-01 15:04:06 AAA A B
3 458 2018-01-15 15:04:06 BBC C D
5 458 2018-01-18 15:04:06 AAA X D
I am using below mentioned query:
SELECT a.ID,a.Type,a.Date,b.Status1,a.Status2,a.Status3
From Table1 a
inner join Table2 b
on a.abc=b.xyz
inner join Table2 c
on a.efg=c.xyz
GROUP BY a.Type
HAVING Count(a.Type)>0
AND b.Status1='AAA'
UNION SELECT a.ID,a.Type,a.Date,b.Status1,a.Status2,a.Status3
FROM Table1 a
inner join Table2 b
on a.abc=b.xyz
inner join Table2 c
on a.efg=c.xyz
GROUP BY a.Type
HAVING Count(a.Type)>0
AND a.Date > (SELECT Date From Table1 GROUP BY Type HAVING b.Status1='AAA' AND Count(Type)>0)
AND ( Status2='A' AND Status3='D' )
OR Status3='D';
You can try something like below
SELECT t.* FROM `t` INNER JOIN
(
SELECT `type` , COUNT(`type`) ct FROM t GROUP BY `type` HAVING ct > 1
) t1
ON t1.type = t.type ORDER BY DATE ASC
I hope this will return what you want.
Try this query .
Hope this will give you the desire output .
SELECT
ID ,
Type ,
Date ,
Status1 ,
Status2 ,
Status3
FROM
[Tabel_Name]
GROUP BY
Type
HAVING
Count(Type)>0
AND
Status1='AAA'
UNION
SELECT
ID ,
Type ,
Date ,
Status1 ,
Status2 ,
Status3
FROM
[Tabel_Name]
GROUP BY
Type
HAVING
Count(Type)>0
AND
Date > (SELECT Date From [Tabel_Name] GROUP BY Type HAVING Status1='AAA' AND Count(Type)>0)
AND
( Status2='C' AND Status3='D' )
OR
Status3='D'
Select idn, sum(tblppmp.total_item) as a_total
sum(tblRequest.Quantity) as b_total
sum(a_total- b_total) as itemsleft
FROM PPMP.dbo.tblppmp, ppmp.dbo.tblrequest
Group by idn
i have my problem how to sum individual items from table1 and table2 and the result will be subtracted to get the answer.
like this
table1
id item
1 2
2 3
3 4
table2
id item
1 1
2 2
3 3
the result i want is like this..
table 3
sum(table.item) - sum(table2.item)
table1.id 1 = 2
table2.id 1 = 1
so (2-1) = 1
id item_left
1 1
2 1
3 1
id item
You could caculate sum for each table first and then subtract them.
select idn,
a_total - ISNULL(r_total,0) as itemsleft
FROM
(
select idn, sum(p.total_item) as p_total
from PPMP.dbo.tblppmp p
group by idn
) p
LEFT JOIN
(
select idn, sum(r.Quantity) as r_total
from ppmp.dbo.tblrequest r
group by idn
) r on p.idn = r.idn
You can not use sum(a_total- b_total). You have to use sum(tblppmp.total_item) - sum(tblRequest.Quantity).
Select tblppmp.idn
, tblppmp.total_item as a_total
,tblRequest.Quantity as b_total
,tblppmp.total_item - tblRequest.Quantity as itemsleft
FROM dbo.tblppmp
INNER JOIN
(SELECT
tblrequest.idn
,sum(tblRequest.Quantity) AS Quantity
FROM tblrequest
WHERE tblrequest.dr_year = 2015
GROUP BY tblrequest.idn) tblrequest ON tblppmp.idn = tblrequest.idn
I have these two tables:
items
itemname description belongs
A1 some_text user1
A2 some_text user1
A3 some_text user1
A4 some_text user1
A5 some_text user1
A1 some_text user2
B2 some_text user2
movements
itemname start_date end_date belongs
A1 2013-02-01 2014-01-12 user1
A1 2014-08-14 NULL user1
A1 2014-10-15 2015-01-01 user1
A2 2013-08-03 2014-08-14 user1
A2 2014-08-14 NULL user1
A3 2013-08-02 2014-08-20 user1
A3 2013-12-05 2014-01-07 user1
A4 2013-07-15 2014-09-13 user1
A4 2014-09-13 NULL user1
A5 2013-07-15 2014-09-13 user1
A5 2015-03-11 2016-03-12 user1
A5 2016-03-12 2016-04-13 user1
A1 2015-08-01 2015-08-12 user2
B2 2015-08-13 2015-08-23 user2
I was playing around with joins and max(date) but didn't come to a working solution.
A result for user1 should looks like this:
itemname description belongs start_date end_date
A1 some_text user1 2014-08-14 NULL
A2 some_text user1 2014-08-14 NULL
A3 some_text user1 2013-08-02 2014-08-20
A4 some_text user1 2014-09-13 NULL
A5 some_text user1 2016-03-12 2016-04-13
I need the line (movement) with the highest (latest, newest) end_date if there is no line where:
end_date = NULL
If there is a line where end_date = NULL, I need this line for that item.
Difficulty here is that sorting for max(start_date) would not work since sometimes there is a timeperiod inside another timeperiod for one item.
I hope you could understand my problem.
Greetings from germany :)
You need something like this
Find the most recent start date for each itemname & belongs combination then join the result back with max start date to get the result
SELECT i.itemname,i.description,i.belongs,m.start_date,m.end_date
FROM items i
JOIN movements m
ON i.itemname = m.itemname
AND i.belongs = m.belongs
JOIN (SELECT itemname,
belongs,
Max(COALESCE(end_date, start_date)) AS max_dt,
Max(end_date) AS max_end_dat,
Max(start_date) AS max_start_dat
FROM movements
GROUP BY itemname,
belongs) m1
ON m1.itemname = m.itemname
AND m1.belongs = m.belongs
AND ( ( m.end_date = m1.max_dt
AND m1.max_dt = m1.max_start_dat )
OR ( m1.max_dt = COALESCE(end_date, m.start_date)
AND m1.max_start_dat <> m1.max_dt )
OR ( m1.max_dt = m.start_date
AND m1.max_end_dat <> m1.max_dt ) )
ORDER BY i.belongs,
i.itemname
SQL FIDDLE DEMO
Update :
SELECT i.itemname,
i.description,
i.belongs,
m.start_date,
m.end_date
FROM items i
JOIN movements m
ON i.itemname = m.itemname
AND i.belongs = m.belongs
JOIN (SELECT itemname,
belongs,
Max(start_date) AS max_dat,
'st' AS indi
FROM movements
WHERE end_date IS NULL
GROUP BY itemname,
belongs
UNION ALL
SELECT itemname,
belongs,
Max(end_date) AS max_dat,
'ed'
FROM movements m
WHERE NOT EXISTS (SELECT 1
FROM movements m1
WHERE m.itemname = m1.itemname
AND m.belongs = m1.belongs
AND end_date IS NULL)
GROUP BY itemname,
belongs) m1
ON m1.itemname = m.itemname
AND m1.belongs = m.belongs
AND ( ( m1.max_dat = m.start_date
AND indi = 'st' )
OR ( m1.max_dat = m.end_date
AND indi <> 'st' ) )
ORDER BY i.belongs,
i.itemname
SQL FIDDLE DEMO
This will be really easy if your RDBMS supports ROW_NUMBER window function or APPLY operator
to select a record from a group of records:
IN ALL the Methods you can join with your Items table to get extra information.
Method-1 use self join:
Select a.*
from yourTable as a
left join YourTable as b
on b.belongs = a.Belongs
and b.Item_Name=a.Item_Name
and b.Start_date>a.Start_Date
where b.Start_Date is null
Method-2, use MaxDate.
with MaxDate as(
Select belongs, Item_Name, Max(Start_Date) as MaxDate
from yourTable
group by belongs, Item_Number
) select * from MaxDate as a
inner join YourTable as b
on b.belongs=a.belongs
and b.Item_Number=a.Item_Number
and b.Start_Date=a.MaxDate
Method-3, use Row_Number to flag the last record in the group
with LastRec as(
select *,
Row_Number() over(partition by belongs, Item_number order by Start_date desc) as RN
From yourTable
) select * from LastRec
where rn=1
Method-4, use sub-query to get the last record in the group.
Select * from your table as a
Where a.StartDate=(Select Max(Start_Date) from yourTable as b Where b.belongs=a.belongs and b.Item_Name=a.Item_Number)
Need some help creating a query that can get me the results I want.
I'm pulling information from 2 tables in the mysql database.
TABLE 1 - tblclients
ID firstname lastname
1 Bob K
2 Mary J
3 Tod M
tblcustomfieldsvalues.RelId = tblclients.ID
TABLE 2 - tblcustomfieldsvalues
ID fieldid RelId value
1 15 3 3500
2 15 2 1500
3 17 3 Calp
4 17 2 Amazon
5 17 2 Calp
TABLE 3 - tblcustomfields (JUST FOR REFERENCE)
ID FieldID name
1 15 Purchase Amount
2 17 Site
Desired Result:
I want to show the Purchase Amount in column 4 (FieldID = 15) where FieldID = 17 and value = 'calp'
ID FirstName LastName Value
1 Tod M 3500
2 Mary J 1500
Current Query:
SELECT tblclients.id, tblclients.firstname, tblclients.lastname, tblcustomfieldsvalues.value FROM tblclients INNER JOIN tblcustomfieldsvalues ON tblclients.id = tblcustomfieldsvalues.relid WHERE tblcustomfieldsvalues.fieldid = 17 AND tblcustomfieldsvalues.value = 'Calp'
Current Result:
ID FirstName LastName Value
1 Tod M Calp
2 Mary J Calp
One approach to this is conditional aggregation:
select c.*, value15 as value
from tblclients c join
(select cfv.relid,
max(case when fieldid = 15 then value end) as value15,
sum(case when fieldid = 17 and value = 'Calp' then 1 else 0 end) as cnt17
from tblcustomfieldsvalues cfv
group by cfv.relid
) cv
where cnt17 > 0;
You can also do this with joins. But you need separate joins for each for each of the fields:
SELECT c.id, c.firstname, c.lastname, cfv15.value
FROM tblclients c INNER JOIN
tblcustomfieldsvalues cfv17
ON c.id = cfv17.relid AND
cvf17.fieldid = 17 AND cfv17.value = 'Calp' INNER JOIN
tblcustomfieldsvalues cfv15
ON c.id = cfv15.relid AND
cvf15.fieldid = 15;
I am not clear what result you are expecting...
First of all I am sure you wrote fieldid=17 to get this result not 47.
If so
Your result is normal. You ask for fieldid 17 and also value 'Calp'.
Do you want fieldid 15 maybe ? Those were the ones has prices...
Or maybe
SELECT tblclients.id, tblclients.firstname, tblclients.lastname, tblcustomfieldsvalues.value FROM tblclients INNER JOIN tblcustomfieldsvalues ON tblclients.id = tblcustomfieldsvalues.relid WHERE tblcustomfieldsvalues.fieldid in (15,17) OR tblcustomfieldsvalues.value = 'Calp'
Your Query:
SELECT tblclients.id, tblclients.firstname, tblclients.lastname, tblcustomfieldsvalues.value FROM tblclients INNER JOIN tblcustomfieldsvalues ON tblclients.id = tblcustomfieldsvalues.relid WHERE tblcustomfieldsvalues.fieldid = 47 AND tblcustomfieldsvalues.value = 'Calp'
I want to count how many times each user has rows within '5' of eachother.
For example, Don - 501 and Don - 504 should be counted, while Don - 501 and Don - 1600 should not be counted.
Start:
Name value
_________ ______________
Don 1235
Don 6012
Don 6014
Don 6300
James 9000
James 9502
James 9600
Sarah 1110
Sarah 1111
Sarah 1112
Sarah 1500
Becca 0500
Becca 0508
Becca 0709
Finish:
Name difference_5
__________ _____________
Don 1
James 0
Sarah 2
Becca 0
Use the ABS() function, in conjunction with a self-join in a subquery:
So, something like:
SELECT name, COUNT(*) / 2 AS difference_5
FROM (
SELECT a.name name, ABS(a.value - b.value)
FROM tbl a JOIN tbl b USING(name)
WHERE ABS(a.value - b.value) BETWEEN 1 AND 5
) AS t GROUP BY name
edited as per Andreas' comment.
Assuming that each name -> value pair is unique, this will get you the count of times the value is within 5 per name:
SELECT a.name,
COUNT(b.name) / 2 AS difference_5
FROM tbl a
LEFT JOIN tbl b ON a.name = b.name AND
a.value <> b.value AND
ABS(a.value - b.value) <= 5
GROUP BY a.name
As you'll notice, we also have to exclude the pairs that are equal to themselves.
But if you wanted to count the number of times each name's values came within 5 of any value in the table, you can use:
SELECT a.name,
COUNT(b.name) / 2 AS difference_5
FROM tbl a
LEFT JOIN tbl b ON NOT (a.name = b.name AND a.value = b.value) AND
ABS(a.value - b.value) <= 5
GROUP BY a.name
See the SQLFiddle Demo for both solutions.
Because the OP also wants de zero counts, we'll need a self- left join. Extra logic is needed if one person has two exactly the same values, these should also be counted only once.
WITH cnts AS (
WITH pair AS (
SELECT t1.zname,t1.zvalue
FROM ztable t1
JOIN ztable t2
ON t1.zname = t2.zname
WHERE ( t1.zvalue < t2.zvalue
AND t1.zvalue >= t2.zvalue - 5 )
OR (t1.zvalue = t2.zvalue AND t1.ctid < t2.ctid)
)
SELECT DISTINCT zname
, COUNT(*) AS znumber
FROM pair
GROUP BY zname
)
, names AS (
SELECT distinct zname AS zname
FROM ztable
GROUP BY zname
)
SELECT n.zname
, COALESCE(c.znumber,0) AS znumber
FROM names n
LEFT JOIN cnts c ON n.zname = c.zname
;
RESULT:
DROP SCHEMA
CREATE SCHEMA
SET
CREATE TABLE
INSERT 0 14
zname | znumber
-------+---------
Sarah | 3
Don | 1
Becca | 0
James | 0
(4 rows)
NOTE: sorry for the CTE, I had not seen th mysql tag,I just liked the problem ;-)
SELECT
A.Name,
SUM(CASE WHEN (A.Value < B.Value) AND (A.Value >= B.Value - 5) THEN 1 ELSE 0 END) Difference_5
FROM
tbl A INNER JOIN
tbl B USING(Name)
GROUP BY
A.Name