I want to get the last activity of my client but i dont know how to that that with two tables that have more than one pivot. Please look at to the example below :
table product
--------------------------------------------------------------------------------------------------------------------------------------
id | name | check_mo (Activity1) | check_mo_account_id | check_pa (Activity2) | check_pa_account_id
--------------------------------------------------------------------------------------------------------------------------------------------
1 | product1 | 01/02/2020 | 63 | 05/02/2020 | 100
2 | product2 | 01/03/2020 | 23 | 10/03/2020 | 63
-----------------------------------------------------------------------------------------------------------------------------------
Table account
--------------------------------
id | name
--------------------------------
23 | name1
63 | name2
100 | name3
--------------------------------
I want this result (last activity is the lastest date of (check_mo and check_pa). and relationship between tables is (account.id => product.check_mo_account_id and product.check_pa_account_id))
------------------------------------------------
id | name | last activity
-------------------------------------------------
23 | name1 | 01/03/2020
63 | name2 | 10/03/2020
100 | name3 | 05/02/2020
-------------------------------------------------
Unpivot the columns. In MySQL, you can use union all. Use join to bring in the names and then a window function to get the most recent date:
select pn.*
from (select pn.*, max(dte) over (partition by name) as max_dte
from ((select n.name, p.check_mo as dte, p.check_mo_account_id as account_id
from product p join
name n
on p.check_mo_account_id = n.id
) union all
(select n.name, p.check_pa, p.check_pa_account_id as account_id, p.check_pa
from product p join
name n
on p.check_mo_account_id = n.id
)
) pn
) pn
where dte = max_dte;
If I understand correctly, you have two check IDs and two check dates in one row, but want to treat them equally, just as if you had just one table with one check ID and one check date per row. Use UNION ALL to get this table. Then find the maximum date per ID and join this to the account table.
select id, account.name, aggregated.last_activity
from account
join
(
select id, max(check) as last_activity
from
(
select check_mo_account_id as id, check_mo as check from product
union all
select check_pa_account_id as id, check_pa as check from product
) unioned
group by id
) aggregated using (id)
order by id;
Related
I am a bit new to write complex SQL queries. There are two tables and we call them employee and status.
I need to filter duplicate records based on the key and status.
Key : |emplyee_dep_id|employee_reg_date|employee_rep_manager|
It is a composite key.
And there is a column in the Employee table called emp_status_id. In the Status table, there are two columns status_code and status_id.
Finally, I need to filter duplicate records based on the composite key with status "promoted" joining two tables.
I have written two queries but need to develop a single query. Could you help me to combine these two queries, please?
Sample data
|emplyee_dep_id|employee_reg_date|employee_rep_manager|status_id|email|
| 1 | 20-01-01 | Anne | 3 |a#a.com|
| 1 | 20-01-01 | Anne | 3 |u#a.com|
| 1 | 20-01-01 | Anne | 3 |y#a.com|
| 1 | 20-01-01 | Anne | 3 |h#a.com|
| 1 | 20-01-01 | Anne | 1 |b#a.com|
|Status_id|status_code|
| 3 | Promoted |
| 1 | Probation |
Query:
SELECT
emp.emplyee_dep_id, emp.employee_reg_date,
emp.employee_rep_manager, employee_status
FROM
employee emp
INNER JOIN
(SELECT
emplyee_dep_id, employee_reg_date, employee_rep_manager,
COUNT(*) AS CountOf
FROM
employee
GROUP BY
emplyee_dep_id, employee_reg_date, employee_rep_manager
HAVING
COUNT(*) > 1) emp1 ON emp.emplyee_dep_id = emp1.emplyee_dep_id
AND emp.employee_reg_date = emp1.employee_reg_date
AND emp.employee_rep_manager = emp1.employee_rep_manager
SELECT
employee_status
FROM
Employee
INNER JOIN
Status ON Employee.status_id = Status.status_id
WHERE
Status.status_code = 'promoted'
Instead of the Employee in the 2nd query, put the 1st query and join with status
SELECT e.*, s.status_code
from
(
SELECT emp.emplyee_dep_id,emp.employee_reg_date,emp.employee_rep_manager,employee_status as status_id
FROM employee emp
INNER JOIN (SELECT
emplyee_dep_id,employee_reg_date,employee_rep_manager, COUNT(*) AS CountOf
FROM employee
GROUP BY emplyee_dep_id,employee_reg_date,employee_rep_manager
HAVING COUNT(*)>1
) emp1
ON emp.emplyee_dep_id=emp1.emplyee_dep_id
AND emp.employee_reg_date=emp1.employee_reg_date
AND emp.employee_rep_manager = emp1.employee_rep_manager
) E
INNER JOIN Staus s
ON E.status_id = s.status_id
where s.status_code = 'promoted'
Group by emplyee_dep_id,employee_reg_date,employee_rep_manager;
And here is the fiddle
I have two column one column associated with another...
Table:base_data
id |---name----|-----des
1 | some name1 | The description1
2 | some name2 | The description2
Table: photos
id |---p_id----|-----photo
1 | 1 | img1s.jpg
2 | 1 | img1w.jpg
3 | 2 | img2.jpg
4 | 2 | img14.jpg
5 | 2 | img15.jpg
I want to select all data from table 1(base_data) and one row from associated row from photos: table how can I do that ????
I don't want to select by greatest n per group I want to select all data from the first table and only one row of the second table which matches with the first table row id, just first match not other.
The Result I want...
id |---name----|---des----|---p_id----|---photo----|
1 | some name |the des..1| 1 | img1s.jpg|
2 | some name |the des..2| 2 | img2.jpg|
I suppose you want to associate base_data with the first photo taken, which should be the one with the lowest photos.id. In MySQL, you could write this as follows: Create an intermediate query which gives - for any p_id - the corresponding record with the lowest id. Then, left join base_data with this intermediate query result. Hope there are not to many typos in it :-) :
select b.id, p2.photo
from base_data b left join
(select p.photo, p.p_id, min(id) from photos p group by p.p_id) p2 on b.id = p2.p_id
If you want the alphanumerically lowest photo name, in MySQL you can do this:
select
t1.*,
t2.photo
from
base_data as t1
left join (
select
p_id,
min(photo) as photo
from
photos
group by
p_id
) as t2 on t2.p_id = t1.id;
I need to join together 2 SQL statements and both of those statements work on their own. But I don't know how to combine both into 1 SQL statement.
I have two tables in 1st statement, TR120 and TR1201.
The SQL is this:
select
PRODUCT, PRICE, QUANTITY, INVOICE.DATE
from
TR1201
left join
(select
DATE, ID as INVOICE_ID, INVOICE
from TR120) as INVOICE on INVOICE.INVOICE_ID = ID
where
INVOICE.DATE >= '2016-06-01' and INVOICE.DATE <= '2016-06-30'
This returns a list of all the products I sold, with price, quantity and date of sales in a specific time frame from 01-06-16 till 30-06-16.
Now I need to find out the latest price that I bought product for in different two tables TR100 and TR1001 based on the product and date of sale from the 1st SQL statement.
select
PRODUCT, PRICE, SUP.DATE
from
TR1001
left join
(select
DATE, ID as SUP_ID, SUP_INVOICE
from TR100) as SUP on SUP.SUP_ID = ID
This returns a list of all the products that I have bought with a price and a date. I only need last record from this query based on product and date of purchased.
TR120
ID | INVOICE | DATE
1 | 000001 |2016-06-05
2 | 000002 |2016-06-15
3 | 000003 |2016-06-25
TR1201
ID | PRODUCT | PRICE A | QUANTITY
1 | A | 2,00 | 5
2 | A | 2,00 | 2
3 | A | 2,00 | 1
TR100
ID | SUP_INVOICE | DATE
1 | 160001 | 2016-05-30
2 | 160002 | 2016-06-16
TR1001
ID | PRODUCT | PRICE B
1 | A | 0,5
2 | A | 0,7
The result I am trying to get is this:
PRODUCT | PRICE A (tr1201) | QUANTITY | DATE (tr100) | PRICE B (tr1001)
A | 2 | 5 | 2016-05-30 | 0,5
A | 2 | 2 | 2016-05-15 | 0,5
A | 2 | 1 | 2016-05-16 | 0,7
That is all I want to do :(
Have you tried first_value?
FIRST_VALUE ( [scalar_expression ] )
OVER ( [ partition_by_clause ] order_by_clause [ rows_range_clause ] )
it works like this:
select distinct id,
first_value(price) over (partition by id (,sup) order by date DESC (latest, ASC for oldest)) as last_price
from table;
Documentation can be found here: https://msdn.microsoft.com/en-us/library/hh213018.aspx
I don't have your tables so cannot test and therefore am providing advice only.
I think what you need is an Outer apply like this instead of joins
select
T1.Product
, T1.Price
, T2.DATE -- Alias this
, T2.Price -- Alias this
, T3.DATE -- Alias this
, T3.Price -- Alias this
from T1
OUTER APPLY (
select top 1
Date
,Price
from table2
WHERE ID = T1.Id AND product = T1.Product-- plus any other joins
ORDER BY Date desc
) as T2
OUTER APPLY (
select top 1
Date
,Price
from table3
WHERE ID = T1.Id AND product = T1.Product-- plus any other joins
ORDER BY Date desc
) as T3
I have two mySQL tables as follows:
[product] table
P_id | Name | Quantity
1 | B | 10
2 | C | 15
3 | A | 8
[attribute] table
P_id | Name | Quantity
1 | Black | 5
1 | Red | 5
2 | Blue | 6
2 | Black | 9
How can I write an SQL query so that it can show the result from the above two tables as follows:
Report:
P_id | Name | Quantity
3 | A | 8
1 | B | 10
1 | Black | 5
1 | Red | 5
2 | C | 15
2 | Black | 9
2 | Blue | 6
These should be sorted on [Name] column, but these should be grouping on P_id column as above. By "grouping" on P_id, I mean "keeping all records with the same P_id next to each other". IS it possible to retrieve as above arrangement using a single SQL query.
SELECT P_id, Name, Quantity FROM (
SELECT P_id, Name, Quantity, Name as parent, 1 as level
FROM product
UNION
SELECT a.P_id, a.Name, a.Quantity, p.Name as parent, 2 as level
FROM attribute a JOIN product p ON a.P_id = p.P_id
) combined ORDER BY parent, level, Name
It should be Union operation, I believe like this:
select * from product union select * from attribute order Name;
Not sure why you wrote you need `group by' since your output is not grouped by any column.
Do you mean that you just need an union of both tables?
You can try this:
Select P_id, Name, Quantity
From product
Union
Select P_id, Name, Quantity
From attribute
Order by 2
SELECT * FROM
(
SELECT P_id, Name , Quantity FROM product
UNION ALL
SELECT P_id, Name , Quantity FROM attribute
) Order by Name
You will have to use grouping my friend. Then you can order on Both of you required columns like this:
SELECT * FROM product UNION SELECT * FROM attribute ORDER BY Name, P_id;
If you want them ordered by P_id and then Name, this should work.
(SELECT P_id, Name, Quantity FROM product)
UNION
(SELECT P_id, Name, Quantity FROM attribute)
ORDER BY P_id, Name;
Ok so its easier to give an example and hopefully some has a solution:
I have table that holds bids:
ID | companyID | userID | contractID | bidAmount | dateAdded
Below is an example set of rows that could be in the table:
ID | companyID | userID | contractID | bidAmount | dateAdded
--------------------------------------------------------------
10 | 2 | 1 | 94 | 1.50 | 1309933407
9 | 2 | 1 | 95 | 1.99 | 1309933397
8 | 2 | 1 | 96 | 1.99 | 1309933394
11 | 103 | 1210 | 96 | 1.98 | 1309947237
12 | 2 | 1 | 96 | 1.97 | 1309947252
Ok so what I would like to do is to be able to get all the info (like by using * in a normal select statement) the lowest bid for each unique contractID.
So I would need the following rows:
ID = 10 (for contractID = 94)
ID = 9 (for contractID - 95)
ID = 12 (for contractID = 96)
I want to ignore all the others. I thought about using DISTINCT, but i haven't been able to get it to return all the columns, only the column I'm using for distinct.
Does anyone have any suggestions?
Thanks,
Jeff
select *
from mytable main
where bidAmount = (
select min(bidAmount)
from mytable
where contractID = main.contractID)
Note that this will return multiple rows if there is more than one record sharing the same minimum bid.
Didn't test it but it should be possible with this query although it might not be really fast:
SELECT * FROM bids WHERE ID IN (
SELECT ID FROM bids GROUP BY contractID ORDER BY MIN(bidAmount) ASC
)
This would be the query for MySQL, maybe you need to adjust it for another db.
You could use a subquery to find the lowest rowid per contractid:
select *
from YourTable
where id in
(
select min(id)
from YourTable
group by
ContractID
)
The problem is that distinct does not return a specific row - it return distinct values, which ( by definition ) could occur on multiple rows.
Subqueries are your answer, and somewhere in the suggestions above is probably the answer. Your subquery need to return the ids or the rows with the minimum bidvalue. Then you can select * from the rows with those ids.