I have 2 mysql tables like in the example below:
CARS:
RaceID CarID Dis Grd Date Time
8 1 200 A 2010-10-10 20.50
8 2 300 A 2010-10-10 30.50
8 3 200 A 2010-10-10 20.10
9 1 200 A 2010-11-10 20.00
12 1 200 A 2011-12-11 19.50
RACES:
RaceId CarID Dis Grd Date Exp_Time
10 1 200 A 2011-11-11
10 2 200 A 2011-11-11
10 3 200 A 2011-11-11
I want to Add data on Races table at column Exp_Time based on data from CARS table.
For example:
RACES.Exp_Time=AVG(CARS.Time)
WHERE
CARS.CarID=RACES.CarID
CARS.Dis=RACES.Dis
CARS.Grd=RACES.Grd
CARS.Date<RACES.Date
The idea is that expected Time is AVG from previous races times on same distance and grd. Future races should be excluded from calculation AVG.
The problem is getting the date condition from RACES table.
I do this query:
UPDATE `RACES` c
INNER JOIN (
SELECT CARS.CarID, CARS.Dis, CARS.Grd, CARS.Date, AVG(Time) AS `Exp_Time`
FROM CARS
WHERE CARS.Date<'2011-11-11'
GROUP BY CarID, Dis, Grd
)
x ON c.CarID=x.CarID AND c.Dis=x.Dis AND c.Grd=x.Grd
SET c.Exp_Time=x.Exp_Time
And it works when I type myseld the date - 2011-11-11
I don't know how to get the data from RACES table.
Can somebody help?
Thanks in advance!
Ivan
UPDATE `RACES` c
INNER JOIN (
SELECT CARS.CarID, CARS.Dis, CARS.Grd, CARS.Date, AVG(Time) AS `Exp_Time`
FROM CARS
WHERE CARS.Date < (SELECT Date
FROM RACES
WHERE CARS.Date<RACES.Date
AND CARS.Grd=RACES.Grd
AND CARS.CarID=RACES.CarID
AND CARS.Dis=RACES.Dis
LIMIT 1
)
GROUP BY CarID, Dis, Grd
)
x ON c.CarID=x.CarID AND c.Dis=x.Dis AND c.Grd=x.Grd
SET c.Exp_Time=x.Exp_Time
2011-11-11 I don't know how to get the data from RACES table.
You can move this predicate to the JOIN condition like so:
UPDATE `RACES` c
INNER JOIN (
SELECT
CarID, Dis, Grd, Date, AVG(Time) AS `Exp_Time`
FROM CARS
GROUP BY CarID, Dis, Grd
)x ON c.CarID = x.CarID
AND c.Dis = x.Dis
AND c.Grd = x.Grd
AND x.DATE(`Date`) < c.DATE(`Date`)
SET c.Exp_Time = x.Exp_Time;
Related
I need help with a query, I have a table ,here is an example
Item Code Qty Price Supplier
1234 1 20 A
1234 3 15 B
1234 6 2 C
4321 2 8 D
4321 7 1 A
4321 9 5 G
5432 8 10 E
5432 3 2 F
5467 5 9 H
5467 5 7 K
I have a subquery which contains distinct Item code, max(price) and 75%of max(price),this is the result.
Item Code Max value Min Value
1234 20 15
4321 8 6
5432 10 7.5
5467 9 6.75
and I need pull only those rows from first table if the price falls within the range of second table for the particular Item Code. Can anyone help?
You might give this a try:
SELECT
a.*
FROM items a
JOIN (
SELECT
item_code,
MAX(Price) as Max_Value,
MAX(Price) * 0.75 as Min_Value
FROM items
GROUP BY item_code) b
ON a.item_code = b.item_code
WHERE a.price between b.Min_Value AND b.Max_Value
order by a.item_code, a.price ASC
I will get first the max price per itemCode and join to the main table using itemCode and chwck that the price is between 75% of max and max price per item.
Select tbl.*
From myTable tbl
Join (
Select item_code,
max(price) as mx,
Round(max(price)*.75,0) as mx75
From myTable
Group by item_code) tab
On tbl.item_code = tab.item_code
And tbl.price between tab.mx75 and tab.mx
Order by 1, 4
I have created the below SQL query to calculate the total income from leases within the next 12 months .
SELECT DISTINCT apartment.addressLine1, lease.monthlyRent, lease.duration, lease.roomNumber, lease.monthlyRent*lease.duration AS totalLeaseRent
FROM `lease`
INNER JOIN apartment on (lease.roomNumber) = (apartment.roomNumber)
left Join tenantLease on tenantLease.leaseID = lease.leaseID
WHERE tenantLease.live = 1 AND lease.duration <= 12
This returns the following result:
AddressLine1 monthlyRent Duration(months) roomNumber totalLeaseRent
Chlorine Gardens1200 9 GF02 10800
May Road 800 12 GF03 9600
Beech Hill 900 8 BG06 7200
Ash Avenue 1000 12 AA04 12000
I now want to be able to have another row to include the total of the totalLeaseRent. Like this:
AddressLine1 monthlyRent Duration(months) roomNumber totalLeaseRent
Chlorine Garden1200 9 GF02 10800
May Road 800 12 GF03 9600
Beech Hill 900 8 BG06 7200
Ash Avenue 1000 12 AA04 12000
TOTAL *total*
I have tried the following code but keep getting the error code:
1222 - The used SELECT statements have a different number of columns
SELECT DISTINCT apartment.addressLine1, lease.monthlyRent, lease.duration, lease.roomNumber, lease.monthlyRent*lease.duration AS totalLeaseRent
FROM `lease`
INNER JOIN apartment on (lease.roomNumber) = (apartment.roomNumber)
left Join tenantLease on tenantLease.leaseID = lease.leaseID
WHERE tenantLease.live = 1 AND lease.duration <= 12
UNION ALL
SELECT 'Total', SUM(lease.monthlyRent * lease.duration)
FROM lease
How do I get this query to run?
Thanks
TRY THIS: We have to follow following three points while working with set operation
1- Each SELECT statement within UNION must have the same number of columns
2- The columns must also have similar data types
3- The columns in each SELECT statement must also be in the same order
SELECT DISTINCT apartment.addressLine1,
lease.monthlyRent,
lease.duration,
lease.roomNumber,
lease.monthlyRent*lease.duration AS totalLeaseRent
FROM `lease`
INNER JOIN apartment on (lease.roomNumber) = (apartment.roomNumber)
left Join tenantLease on tenantLease.leaseID = lease.leaseID
WHERE tenantLease.live = 1 AND lease.duration <= 12
UNION ALL
SELECT 'Total', NULL, NULL, NULL, SUM(lease.monthlyRent * lease.duration)
FROM lease
table:tab1
id date_time zoneid accountid slotid trequest bidder width height
_50832 2017-09-04 15:41:06 153 1654 153x468x60 10 aaa 468 60
_50832 2017-09-04 15:41:06 152 1654 152x468x60 10 bbb 468 60
table:tab2
id date_time zoneid accountid slotid bidder count
_50832 2017-09-04 15:41:06 152 1654 152x468x60 bbb 6
_50832 2017-09-04 15:41:06 152 1654 152x468x60 bbb 4
_50832 2017-09-04 15:41:06 153 1654 153x468x60 aaa 9
_50832 2017-09-04 15:41:06 153 1654 153x468x60 aaa 1
below is my query:
SELECT SUM(req.trequest) as REQ, SUM(win.count) as IMP
FROM tab1 as req
JOIN tab2 as win ON (req.id=win.id AND req.zoneid=win.zoneid)
GROUP BY req.zoneid
I get below result,
REQ IMP
20 10
20 10
IMP count is correct but I get wrong REQ count. My expected result is
REQ IMP
10 10
10 10
How to get my expected result?
Lets find the sum of trequest and count separately based on zoneid and id.Then use these two results ( t1 and t2 ) in the inner join.
Count mismatch problem shown in the question occur due to multiple rows satisfying the joining conditions.
In this solution we will only have one entry for each zoneid in both the results ( t1 and t2 ). So the problem is avoided.
Note: You can remove the id column from the GROUP BY clause if it doesn't make any difference.
SELECT t1.id, t1.zoneid, t1.REQ, t2.IMP FROM
(SELECT id,zoneid,SUM(trequest) as REQ
FROM tab1 GROUP BY zoneid,id ) t1
INNER JOIN
(SELECT id,zoneid SUM(win.count) as IMP
FROM tab2 GROUP BY zoneid,id ) t2
ON t1.id = t2.id
AND t1.zoneid = t2.zoneid
Let's try first sumwin.count and group records in sub-query, after it join tables. Try in following:
SELECT SUM(req.trequest) as REQ, SUM(win.count) as IMP
FROM tab1 as req
JOIN (
SELECT SUM(win.count) as IMP, win.zoneid, win.id
FROM tab2 as win
GROUP BY win.zoneid, win.id) AS win ON req.id=win.id AND req.zoneid=win.zoneid
GROUP BY req.zoneid
Instead of req.zoneid. You should try win.zoneid. What seems is that the rows in table 1 are counted multiple times as zoneid in table 2 comes twice. So win.zoneid would group it and avoid the repetition.
Updated: The solution posted by #mayur panchal is the correct one as you don't need to SUM the rows in first table as they belong to different zoneid. If you SUM them you will obviously get the 20 repeated twice.
Table 1:
Date PlacementID CampaignID Impressions
04/01/2014 100 10 1000
04/01/2014 101 10 1500
04/01/2014 100 11 500
Table 2:
Date PlacementID CampaignID Cost
04/01/2014 100 10 5000
04/01/2014 101 10 6000
04/01/2014 100 11 7000
04/01/2014 103 10 8000
When I have joined this table using Full Join and Left Join statement, I am not able to get uncommon record which is last row in table2 that display PlacementID 103 and campaignID 10 and Cost 8000. However I have searched all raw data and file but this missing records are not common between two sources. However, I want to include this records in final table. How can I do that? This two table are two different source and I have got results only common records.
Moreover, when I found out that missing value is exact value that are required in final figure so want to include every thing. I am including my SQL script below:
SELECT A.palcementid,
A.campaignid,
A.date,
Sum(A.impressions) AS Impressions,
Sum(CASE
WHEN C.placement_count > 1 THEN ( B.cost / C.placement_count )
ELSE B.cost
END) AS Cost
FROM table1 A
FULL JOIN table2 B
ON A.placementid = B.placementid
AND A.campaignid = B.campaignid
AND A.date = B.date
LEFT JOIN (SELECT Count(A.placementid) AS Placement_Count,
placementid. campaignid,
date
FROM table1
GROUP BY placementid,
campaignid,
date) c
ON A.placementid = C.placementid
AND A.campaignid = C.campaignid
AND A.date = C.date
GROUP BY A.placementid,
A.campaignid,
A.date
I am dividing Cost by placement because in source the cost was allocated for one placement only and one time so I have to divide those because in actual table the same Placementid repeat more than 1 times on same date.
As you didn't provide any expected output I guessing here but if the result you want is this:
PlacementID CampaignID Date Impressions Cost
----------- ----------- ----------------------- ----------- -----------
100 10 2014-04-01 02:00:00.000 1000 5000
100 11 2014-04-01 02:00:00.000 500 7000
101 10 2014-04-01 02:00:00.000 1500 6000
103 10 2014-04-01 02:00:00.000 NULL 8000
Then the following query should do it:
SELECT COALESCE(A.PlacementID,b.placementid) AS PlacementID,
COALESCE(A.campaignid, b.campaignid) AS CampaignID,
COALESCE(A.date, b.date) AS [Date],
SUM(A.impressions) AS Impressions,
SUM(CASE
WHEN C.placement_count > 1 THEN ( B.cost / C.placement_count )
ELSE B.cost
END ) AS Cost
FROM table1 A
FULL JOIN table2 B
ON A.[PlacementID] = B.placementid
AND A.campaignid = B.campaignid
AND A.date = B.date
LEFT JOIN (SELECT COUNT(PlacementID) AS Placement_Count,
placementid, campaignid,
date
FROM table1
GROUP BY placementid,
campaignid,
date) c
ON A.[PlacementID] = C.placementid
AND A.campaignid = C.campaignid
AND A.date = C.date
GROUP BY COALESCE(A.PlacementID, B.PlacementID),
COALESCE(A.campaignid, b.campaignid),
COALESCE(A.date, b.date)
Sample SQL Fiddle
I was successful in writing the query that lists salesmen that did sell to a particular customer, but not those that have not. I suspect it is because the same salesmen that sold to the specific customer, also sold to other customers.
select a.name from salesperson a inner join orders b on
a.salesperson_id = b.salesperson_id where cust_id="4";
I was thinking that modifying the same query like this would do the trick:
.... a.salesperson_id <> b.salesperson_id where cust_id="4";
But the result lists all the salesmen. This is most likely due to the fact that the same salesmen that were returned in the original query, also sold to other customers
The 3 tables look like this:
Salesperson table
salesperson_ID, Name, Age, Salary
1 Abe 61 140000
2 Bob 34 44000
5 Chris 34 40000
7 Dan 41 52000
8 Ken 57 115000
11 Joe 38 38000
Customer table
cust_ID, Name, City Industry Type
4 faralon sacramento H
6 Apple cupertino S
7 Honda NY B
9 Kolb Oshkosh B
Orders table
Number, Order_date, cust_id, salesperson_id, Amount
10 8/2/1996 4 2 540
20 1/30/1999 4 8 1800
30 7/14/1995 9 1 460
40 1/29/1998 7 2 2400
50 2/3/1998 6 7 600
60 3/2/1998 6 7 720
70 5/6/1998 9 7 150
Any help would be greatly appreciated. ~Alpinehyker
You can do something like this:
select a.name from salesperson a
left join orders b on a.salesperson_id = b.salesperson_id and b.cust_id="4"
where b.Number is null
So, get all salepersons, left join to orders for customer 4, and return only rows where there is no such order.
I am assuming that Number is the primary key for Orders, or at least not null.
All salespeople who have NOT sold to customer_ID 4:
SELECT s.Name FROM Salesperson AS s
LEFT JOIN Orders AS o
ON s.salesperson_ID = o.salesperson_ID
WHERE o.customer_ID <> 4
GROUP BY o.salesperson_ID;
Perhaps this will work
SELECT
s.*
FROM `Salesperson` AS s
LEFT JOIN `Orders` AS o ON o.`salesperson_id` = s.`salesperson_ID`
WHERE
o.`cust_id` NOT IN (4)
GROUP BY s.`salesperson_ID`;
Answer to your 2nd question:
SELECT
COUNT(*) AS num_of_orders
,s.`Name`
FROM `Salesperson` AS s
LEFT JOIN `Orders` AS o ON o.`salesperson_id` = s.`salesperson_ID`
GROUP BY s.`salesperson_ID`
HAVING num_of_orders >= 2;
...and 3rd question. (assuming you have your highAchiever table ready)
INSERT INTO `highAchiever`
(`Name`,`Age`)
SELECT
`Name`
,`Age`
FROM `Salesperson`
WHERE
`Salary` >= 100000;